Import the rest of the core functionality of the internal apparmor
development tree (trunk branch). From svn repo version 6381.
504
changehat/libapparmor/COPYING.LGPL
Normal file
|
@ -0,0 +1,504 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
117
changehat/libapparmor/Makefile
Normal file
|
@ -0,0 +1,117 @@
|
|||
# $Id: Makefile 6262 2006-02-11 07:30:00Z steve $
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2004, 2005, 2006 NOVELL (All rights reserved)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2.1 of the GNU Lesser
|
||||
# General Public License published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
NAME := libapparmor
|
||||
all:
|
||||
COMMONDIR:=$(strip $(shell if [ -d "../common/" ] ; then \
|
||||
echo "../common/" ; \
|
||||
elif [ -d "../../common/" ] ; then \
|
||||
echo "../../common/" ; \
|
||||
else \
|
||||
echo "/common_dir_not_found" ; \
|
||||
fi))
|
||||
|
||||
include Make.rules
|
||||
|
||||
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
|
||||
ifeq ($(COMMONDIR_EXISTS), true)
|
||||
Make.rules: $(COMMONDIR)/Make.rules
|
||||
ln -f $(COMMONDIR)/Make.rules .
|
||||
endif
|
||||
|
||||
SO_VERS = 1
|
||||
DESTDIR =
|
||||
LIB = lib/
|
||||
LIBDIR = /usr/${LIB}
|
||||
|
||||
TARGET=libapparmor
|
||||
TARGETS=${TARGET}.so ${TARGET}.a
|
||||
|
||||
OLDTARGET=libimmunix.so.1
|
||||
|
||||
OBJECTS=change_hat.o
|
||||
TESTS=tst-sgdh tst-cdh tst-sgkey tst-sgdh-static tst-cdh-static tst-sgkey-static
|
||||
|
||||
CFLAGS=-g -O2 -Wall -Wstrict-prototypes -pipe
|
||||
EXTRA_CFLAGS=$(CFLAGS) -fpic -D_REENTRANT
|
||||
ARFLAGS=-rcs
|
||||
|
||||
TEST_CFLAGS=$(CFLAGS) $(CANARY_FLAG) $(FORMATGUARD_FLAG)
|
||||
TEST_LDFLAGS= -L. -limmunix
|
||||
|
||||
all: ${TARGETS} ${OLDTARGET}
|
||||
|
||||
%.o: %.c
|
||||
$(CC) ${EXTRA_CFLAGS} -c -shared -o $@ $<
|
||||
|
||||
${TARGET}.so: ${OBJECTS}
|
||||
${CC} ${EXTRA_CFLAGS} -o $@.$(SO_VERS) -Wl,-soname,$@.$(SO_VERS) -Wl,--version-script=${TARGET}.map -W,-z,defs -shared -dynamic $^
|
||||
ln -fs $@.$(SO_VERS) $@
|
||||
|
||||
${OLDTARGET}: ${OBJECTS} libimmunix_warning.o
|
||||
${CC} ${EXTRA_CFLAGS} -o $@ -Wl,-soname,$@ -Wl,--version-script=${TARGET}.map -W,-z,defs -shared -dynamic $^
|
||||
|
||||
${TARGET}.a: ${OBJECTS}
|
||||
ar ${ARFLAGS} $@ $^
|
||||
|
||||
${POSTINSTALLBIN}: ${POSTINSTALLBIN}.c
|
||||
$(CC) -static -Os -o $@ $(CANARY_FLAG) $(FORMATGUARD_FLAG) $^
|
||||
|
||||
# Ugh, dunno how to do an auto rule for the TESTS
|
||||
tst-sgdh: tst-sgdh.c ${TARGET}.so
|
||||
$(CC) ${TEST_CFLAGS} -o $@ $< ${TEST_LDFLAGS}
|
||||
|
||||
tst-cdh: tst-cdh.c ${TARGET}.so
|
||||
$(CC) ${TEST_CFLAGS} -o $@ $< ${TEST_LDFLAGS}
|
||||
|
||||
tst-sgkey: tst-sgkey.c ${TARGET}.so
|
||||
$(CC) ${TEST_CFLAGS} -o $@ $< ${TEST_LDFLAGS}
|
||||
|
||||
tst-sgdh-static: tst-sgdh.c ${TARGET}.a
|
||||
$(CC) -static ${TEST_CFLAGS} -o $@ $< ${TEST_LDFLAGS}
|
||||
|
||||
tst-cdh-static: tst-cdh.c ${TARGET}.a
|
||||
$(CC) -static ${TEST_CFLAGS} -o $@ $< ${TEST_LDFLAGS}
|
||||
|
||||
tst-sgkey-static: tst-sgkey.c ${TARGET}.a
|
||||
$(CC) -static ${TEST_CFLAGS} -o $@ $< ${TEST_LDFLAGS}
|
||||
|
||||
check: $(TESTS)
|
||||
-LD_LIBRARY_PATH=. ./tst-sgdh
|
||||
-LD_LIBRARY_PATH=. ./tst-cdh
|
||||
-LD_LIBRARY_PATH=. ./tst-sgkey
|
||||
-./tst-sgdh-static
|
||||
-./tst-cdh-static
|
||||
-./tst-sgkey-static
|
||||
|
||||
.PHONY: install
|
||||
install: $(TARGETS)
|
||||
install -d $(DESTDIR)/${LIB} $(DESTDIR)${LIBDIR}
|
||||
install -d ${DESTDIR}/usr/include/sys
|
||||
mv -f $(TARGET).so.$(SO_VERS) $(TARGET)-$(VERSION)-$(RELEASE).so.$(SO_VERS)
|
||||
install -m 755 $(TARGET)-$(VERSION)-$(RELEASE).so.$(SO_VERS) ${DESTDIR}/${LIB}
|
||||
ln -sf $(TARGET)-$(VERSION)-$(RELEASE).so.$(SO_VERS) ${DESTDIR}/${LIB}/$(TARGET).so.$(SO_VERS)
|
||||
install -m 755 $(TARGET).a ${DESTDIR}${LIBDIR}
|
||||
install -m 644 apparmor.h ${DESTDIR}/usr/include/sys
|
||||
ln -sf /${LIB}/$(TARGET).so.$(SO_VERS) ${DESTDIR}${LIBDIR}/$(TARGET).so
|
||||
# compatability with old libimmunix
|
||||
install -m 755 $(OLDTARGET) ${DESTDIR}/${LIB}
|
||||
ln -sf apparmor.h ${DESTDIR}/usr/include/sys/immunix.h
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f *.o $(TARGET)*.so* ${TARGETS} ${OLDTARGET}
|
||||
rm -f ${NAME}-${VERSION}*.tar.gz ${TESTS} $(NAME)-*.tgz ${SPECFILE}
|
21
changehat/libapparmor/apparmor.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* $Id: apparmor.h 6203 2006-02-02 22:03:41Z steve $
|
||||
|
||||
Copyright (c) 2003, 2004, 2005, 2006 Novell, Inc. (All rights reserved)
|
||||
|
||||
The libapparmor library is licensed under the terms of the GNU
|
||||
Lesser General Public License, version 2.1. Please see the file
|
||||
COPYING.LGPL.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_APPARMOR_H_
|
||||
#define _SYS_APPARMOR_H 1
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Prototype for change_hat as defined by the AppArmor project
|
||||
* <http://forge.novell.com/modules/xfmod/project/?apparmor> */
|
||||
extern int change_hat(const char *subprofile, unsigned int magic_token);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* sys/apparmor.h */
|
85
changehat/libapparmor/change_hat.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* $Id: change_hat.c 6288 2006-02-27 17:29:04Z steve $
|
||||
|
||||
Copyright (c) 2003, 2004, 2005, 2006 Novell, Inc. (All rights reserved)
|
||||
|
||||
The libapparmor library is licensed under the terms of the GNU
|
||||
Lesser General Public License, version 2.1. Please see the file
|
||||
COPYING.LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for asprintf */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
int change_hat(char *subprofile, unsigned int token)
|
||||
{
|
||||
int rc = -1;
|
||||
int fd, ret, len = 0, ctlerr = 0;
|
||||
char *buf = NULL;
|
||||
const char *cmd = "changehat";
|
||||
char *ctl = NULL;
|
||||
pid_t tid = syscall(SYS_gettid);
|
||||
|
||||
/* both may not be null */
|
||||
if (!(token || subprofile)) {
|
||||
errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (subprofile && strnlen(subprofile, PATH_MAX + 1) > PATH_MAX) {
|
||||
errno = EPROTO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
len = asprintf(&buf, "%s %08x^%s", cmd, token,
|
||||
subprofile ? subprofile : "");
|
||||
if (len < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctlerr = asprintf(&ctl, "/proc/%d/attr/current", tid);
|
||||
if (ctlerr < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd = open(ctl, O_WRONLY);
|
||||
if (fd == -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = write(fd, buf, len);
|
||||
if (ret != len) {
|
||||
int saved;
|
||||
if (ret != -1) {
|
||||
errno = EPROTO;
|
||||
}
|
||||
saved = errno;
|
||||
(void)close(fd);
|
||||
errno = saved;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
(void)close(fd);
|
||||
|
||||
out:
|
||||
if (buf) {
|
||||
/* clear local copy of magic token before freeing */
|
||||
memset(buf, '\0', len);
|
||||
free(buf);
|
||||
}
|
||||
if (ctl) {
|
||||
free(ctl);
|
||||
}
|
||||
return rc;
|
||||
}
|
13
changehat/libapparmor/libapparmor.map
Normal file
|
@ -0,0 +1,13 @@
|
|||
IMMUNIX_1.0 {
|
||||
global:
|
||||
change_hat;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
APPARMOR_1.0 {
|
||||
global:
|
||||
change_hat;
|
||||
local:
|
||||
*;
|
||||
};
|
185
changehat/libapparmor/libapparmor.spec.in
Normal file
|
@ -0,0 +1,185 @@
|
|||
# $Id: libapparmor.spec.in 6284 2006-02-24 17:11:53Z steve $
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2004, 2005, 2006 NOVELL (All rights reserved)
|
||||
#
|
||||
# This software is licensed under the terms of the GNU Lesser General
|
||||
# Public License, version 2.1. Please see the file COPYING.LGPL.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# norootforbuild
|
||||
#
|
||||
# Check first to see if distro is already defined. It should be defined
|
||||
# by our makefile
|
||||
%if ! %{?distro:1}0
|
||||
%define distro suse
|
||||
%endif
|
||||
|
||||
# Check to see what architecture we are building on so we know where
|
||||
# the lib should be installed.
|
||||
# Note: alpha and ia64 are 64bit systems but they have no 32 bit userland
|
||||
# so they install their libs to /lib instead of /lib64
|
||||
# FIXME: will see what happens when we need to do a 64bit build on RHEL
|
||||
%ifarch x86_64 mips64 ppc64 sparc64 s390x
|
||||
%define build64 1
|
||||
%endif
|
||||
# else anything that doesn't specifically have a lib64 dir
|
||||
# i386 i686 mips ppc sparc arm alpha ia64
|
||||
|
||||
Name: libapparmor
|
||||
Summary: Library to provide key AppArmor symbols
|
||||
Version: @@immunix_version@@
|
||||
Release: 6
|
||||
%if %distro == "suse"
|
||||
Group: System/Libraries
|
||||
%else
|
||||
Group: System Environment/Libraries
|
||||
%endif
|
||||
Source: %{name}-%{version}-@@repo_version@@.tar.gz
|
||||
License: LGPL
|
||||
BuildRoot: %{?_tmppath:}%{!?_tmppath:/var/tmp}/%{name}-%{version}-build
|
||||
URL: http://forge.novell.com/modules/xfmod/project/?apparmor
|
||||
BuildRequires: glibc-devel
|
||||
%if %{?build64:1}0
|
||||
#BuildRequires: linux32
|
||||
%endif
|
||||
Obsoletes: libimmunix
|
||||
Provides: libimmunix
|
||||
|
||||
%description
|
||||
This package provides the libapparmor library, which contains the change_hat(2)
|
||||
symbol, used for sub-process confinement by AppArmor. Applications that
|
||||
wish to make use of change_hat(2) need to link against this library.
|
||||
This package is part of a suite of tools that used to be named SubDomain.
|
||||
|
||||
%prep
|
||||
%if %{?build64:1}0
|
||||
%setup -q -c -n %{name}32
|
||||
%setup -D -q
|
||||
%else
|
||||
%setup -q
|
||||
%endif
|
||||
|
||||
|
||||
%build
|
||||
[ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT}
|
||||
|
||||
%if %{?build64:1}0
|
||||
# build 32 bit version first
|
||||
%define CFLAGS32 "-g -O2 -Wall -Wstrict-prototypes -pipe -fpic -m32"
|
||||
%ifarch x86_64
|
||||
%define env32 linux32
|
||||
%endif
|
||||
%ifarch mips64
|
||||
# FIXME don't know what's supposed to be here
|
||||
%define env32 mips32
|
||||
%endif
|
||||
%ifarch ppc64
|
||||
%define env32 powerpc32
|
||||
%endif
|
||||
%ifarch sparc64
|
||||
%define env32 sparc32
|
||||
%endif
|
||||
%ifarch s390x
|
||||
%define env32 s390
|
||||
# s390 isn't actually 32bit it an odd ball 31bit machine
|
||||
%undefine CFLAGS32
|
||||
%define CFLAGS32 "-g -O2 -Wall -Wstrict-prototypes -pipe -fpic -m31"
|
||||
%endif
|
||||
# FIXME - disabled 32bit builds on 64bit platforms
|
||||
echo "FIXME - disabled 32bit builds on 64bit platforms"
|
||||
#%{env32} make CFLAGS=%{CFLAGS32} -C ../%{name}32/%{name}-%{version}
|
||||
%endif
|
||||
|
||||
make CFLAGS="${RPM_OPT_FLAGS}"
|
||||
|
||||
%install
|
||||
[ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT}
|
||||
%if %{?build64:1}0
|
||||
# FIXME - disabled 32bit builds on 64bit platforms
|
||||
echo "FIXME - disabled 32bit installs on 64bit platforms"
|
||||
#make install DESTDIR=${RPM_BUILD_ROOT} LIB=lib -C ../%{name}32/%{name}-%{version}
|
||||
%endif
|
||||
make install DESTDIR=${RPM_BUILD_ROOT} LIB=%{_lib} VERSION=%{version} RELEASE=%{release}
|
||||
|
||||
# don't use -p here, breaks slackware package builds
|
||||
%post
|
||||
/sbin/ldconfig
|
||||
|
||||
%postun
|
||||
/sbin/ldconfig
|
||||
|
||||
%files
|
||||
%defattr (-,root,root)
|
||||
%if %{?build64:1}0
|
||||
# FIXME - disabled 32bit builds on 64bit platforms
|
||||
#/lib/lib*
|
||||
#/usr/lib/lib*
|
||||
%endif
|
||||
/%{_lib}/lib*
|
||||
%{_libdir}/lib*
|
||||
%{_prefix}/include/sys/*.h
|
||||
%doc COPYING.LGPL
|
||||
|
||||
%changelog
|
||||
* Fri Feb 17 2006 Seth Arnold <seth.arnold@suse.de> 2.0-4.1
|
||||
- use gettid() instead of /proc/self
|
||||
* Fri Feb 10 2006 Steve Beattie <sbeattie@suse.de> 2.0-3.2
|
||||
- Use RPM_OPT_FLAGS
|
||||
- Fix installed library version to match specfile version
|
||||
* Wed Feb 1 2006 Steve Beattie <sbeattie@suse.de> 2.0-3.1
|
||||
- Fix prototype to match change_hat(2) manpage
|
||||
* Mon Jan 23 2006 Steve Beattie <sbeattie@suse.de> 2.0-3
|
||||
- Rename to libapparmor.so and apparmor.h
|
||||
* Thu Jan 5 2006 Steve Beattie <sbeattie@suse.de> 2.0-2
|
||||
- Add svn repo number to tarball
|
||||
* Wed Dec 7 2005 Steve Beattie <sbeattie@suse.de> 2.0-1
|
||||
- Reset version for inclusion is SUSE autobuild
|
||||
* Wed Dec 7 2005 Steve Beattie <sbeattie@suse.de> 1.99-8
|
||||
- Disable 32bit builds on 64bit platforms for now
|
||||
* Mon Dec 5 2005 Steve Beattie <sbeattie@suse.de> 1.99-7
|
||||
- Rename package to libapparmor
|
||||
* Wed Aug 10 2005 Steve Beattie <sbeattie@suse.de> 1.99-6_imnx
|
||||
- Cleanup some of the deprecated exported symbols
|
||||
* Thu Aug 4 2005 John Johansen <jjohansen@novell.com> 1.99-5_imnx
|
||||
- and -m31 flag for s390
|
||||
* Mon Jul 11 2005 Steve Beattie <sbeattie@novell.com> 1.99-4_imnx
|
||||
- get rid of libimmunix_post_upgrade
|
||||
- Re-license to LGPL
|
||||
- update description
|
||||
* Fri May 27 2005 Steve Beattie <steve@immunix.com> 1.99-3_imnx
|
||||
- Clear token buffer before freeing.
|
||||
- Error handling cleanup.
|
||||
* Fri Feb 18 2005 Steve Beattie <steve@immunix.com> 1.99-2_imnx
|
||||
- Use the right command for the 32bit env on 64bit platforms
|
||||
- Support for 64bit builds on systems with combined 32/64 support
|
||||
* Fri Feb 4 2005 Seth Arnold <sarnold@immunix.com> 1.99-1_imnx
|
||||
- Reversion to 1.99
|
||||
* Mon Nov 8 2004 Steve Beattie <steve@immunix.com> 1.2-3_imnx
|
||||
- Finish conversion to slack-capable infrastructure.
|
||||
* Thu Oct 28 2004 Steve Beattie <steve@immunix.com> 1.2-2_imnx
|
||||
- Added a 'make install' target for prelim slack support
|
||||
* Tue Oct 12 2004 Steve Beattie <steve@immunix.com> 1.2-1_imnx
|
||||
- Bump version after shass-1.1 branched off
|
||||
* Thu Sep 23 2004 Steve Beattie <steve@immunix.com> 1.0-13_imnx
|
||||
- Vastly simplify the string handling in change_hat().
|
||||
* Thu Sep 9 2004 Steve Beattie <steve@immunix.com> 1.0-12_imnx
|
||||
- Conditionalize group the package shows up in.
|
||||
* Thu Sep 9 2004 Steve Beattie <steve@immunix.com> 1.0-11_imnx
|
||||
- Fix so change_hat functions correctly even when the token is zero.
|
||||
* Thu Sep 2 2004 Steve Beattie <steve@immunix.com> 1.0-10_imnx
|
||||
- Added that it provides %{_prefix}/sbin/libimmunix_post_upgrade, this
|
||||
was somehow breaking yast.
|
||||
* Mon Aug 30 2004 Steve Beattie <steve@immunix.com> 1.0-9_imnx
|
||||
- Copyright cleanups.
|
||||
* Wed Jul 21 2004 Steve Beattie <steve@immunix.com> 1.0-8_imnx
|
||||
- add basis for conditional distro support
|
||||
* Thu May 28 2004 Tony Jons <tony@immunix.com> 1.0-7_imnx
|
||||
- Add "changehat" command word to start of string written to /proc/pid/attr
|
23
changehat/libapparmor/libimmunix_warning.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* $Id:$
|
||||
|
||||
Copyright (c) 2006 Novell, Inc. (All rights reserved)
|
||||
The libimmunix library is licensed under the terms of the GNU
|
||||
Lesser General Public License, version 2.1. Please see the file
|
||||
COPYING.LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
void __libimmunix_warning(void) __attribute__ ((constructor));
|
||||
void __libimmunix_warning(void)
|
||||
{
|
||||
extern const char *__progname; /* global from linux crt0 */
|
||||
openlog (__progname, LOG_PID|LOG_PERROR, LOG_USER);
|
||||
syslog(LOG_NOTICE,
|
||||
"%s links against libimmunix.so, which is deprecated. "
|
||||
"Please link against libapparmor instead\n",
|
||||
__progname);
|
||||
closelog();
|
||||
|
||||
}
|
504
changehat/mod_apparmor/COPYING.LGPL
Normal file
|
@ -0,0 +1,504 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
59
changehat/mod_apparmor/Makefile
Normal file
|
@ -0,0 +1,59 @@
|
|||
# $Id: Makefile 6135 2006-01-25 19:58:44Z steve $
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2004, 2005 NOVELL (All rights reserved)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
NAME:=apache2-mod-apparmor
|
||||
all:
|
||||
COMMONDIR=../common/
|
||||
|
||||
include Make.rules
|
||||
|
||||
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
|
||||
ifeq ($(COMMONDIR_EXISTS), true)
|
||||
Make.rules: $(COMMONDIR)/Make.rules
|
||||
ln -f $(COMMONDIR)/Make.rules .
|
||||
endif
|
||||
|
||||
all: rpm
|
||||
|
||||
TARGET:=mod_apparmor.so
|
||||
APXS:=$(shell if [ -x "/usr/sbin/apxs2" ] ; then \
|
||||
echo "/usr/sbin/apxs2" ; \
|
||||
elif [ -x "/usr/sbin/apxs" ] ; then \
|
||||
echo "/usr/sbin/apxs" ; \
|
||||
else \
|
||||
echo "apxs" ; \
|
||||
fi )
|
||||
APXS_INSTALL_DIR=$(shell ${APXS} -q LIBEXECDIR)
|
||||
DESTDIR=
|
||||
LIBAPPARMOR_FLAGS=$(shell if [ -f /usr/lib/libapparmor.so -o -f /usr/lib64/libapparmor.so ] ; then \
|
||||
echo -lapparmor ; \
|
||||
else \
|
||||
echo -DUSE_COMPAT_IMMUNIX_H -limmunix ;\
|
||||
fi)
|
||||
|
||||
%.so: %.c
|
||||
${APXS} ${LIBAPPARMOR_FLAGS} -c $<
|
||||
mv .libs/$@ .
|
||||
|
||||
.PHONY: install
|
||||
install: ${TARGET}
|
||||
mkdir -p ${DESTDIR}/${APXS_INSTALL_DIR}
|
||||
install -m 755 $< ${DESTDIR}/${APXS_INSTALL_DIR}
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf .libs
|
||||
rm -f ${NAME}*.tar.gz *.la *.lo *.so *.o *.slo
|
200
changehat/mod_apparmor/apache2-mod-apparmor.spec.in
Normal file
|
@ -0,0 +1,200 @@
|
|||
# $Id: apache2-mod-apparmor.spec.in 6353 2006-03-31 02:26:46Z sarnold $
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2004, 2005 NOVELL (All rights reserved)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
# norootforbuild
|
||||
|
||||
# Check first to see if distro is already defined.
|
||||
|
||||
%if ! %{?distro:1}0
|
||||
%define distro suse
|
||||
%endif
|
||||
|
||||
# this is required to be underscore
|
||||
%define module_name mod_apparmor
|
||||
|
||||
Summary: AppArmor module for apache2.
|
||||
Name: apache2-mod-apparmor
|
||||
Version: @@immunix_version@@
|
||||
Release: 7.2
|
||||
Group: Applications/System
|
||||
Source0: %{name}-%{version}-@@repo_version@@.tar.gz
|
||||
License: LGPL
|
||||
BuildRoot: %{?_tmppath:}%{!?_tmppath:/var/tmp}/%{name}-%{version}-build
|
||||
Url: http://forge.novell.com/modules/xfmod/project/?apparmor
|
||||
Prereq: libapparmor
|
||||
BuildRequires: libapparmor
|
||||
Obsoletes: mod_change_hat mod-change-hat mod-apparmor
|
||||
Provides: mod_change_hat mod-change-hat mod-apparmor
|
||||
|
||||
%if %{distro} == "suse"
|
||||
%define apxs /usr/sbin/apxs2
|
||||
%define apache_mmn %(MMN=$(%{apxs} -q LIBEXECDIR)_MMN; test -x $MMN && $MMN)
|
||||
Prereq: apache2-prefork
|
||||
Prereq: apparmor-parser
|
||||
BuildRequires: apache2-devel
|
||||
Requires: apache2 %{apache_mmn}
|
||||
%else
|
||||
%if %{distro} == "redhat" || %{distro} == "rhel4"
|
||||
%define apxs /usr/sbin/apxs
|
||||
Prereq: httpd
|
||||
BuildRequires: httpd-devel
|
||||
%endif
|
||||
%endif
|
||||
%define module_path %(%{apxs} -q LIBEXECDIR)
|
||||
%define apache_sysconfdir %(%{apxs} -q SYSCONFDIR)
|
||||
%define my_bin_dir /usr/lib/%{name}
|
||||
|
||||
%description
|
||||
apache2-mod-apparmor adds support to apache2 to provide AppArmor confinement
|
||||
to individual cgi scripts handled by apache modules like mod_php and
|
||||
mod_perl.
|
||||
This package is part of a suite of tools that used to be named SubDomain.
|
||||
|
||||
%prep
|
||||
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
make %{module_name}.so APXS=%{apxs}
|
||||
%{__strip} -g %{module_name}.so
|
||||
|
||||
%install
|
||||
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
mkdir -p ${RPM_BUILD_ROOT}
|
||||
make install DESTDIR=${RPM_BUILD_ROOT} DISTRO=%{distro}
|
||||
|
||||
%if %{distro} == "suse"
|
||||
mkdir -p ${RPM_BUILD_ROOT}/%{my_bin_dir}
|
||||
mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/apache2-prefork/
|
||||
ln -s %{module_path}/%{module_name}.so ${RPM_BUILD_ROOT}%{_libdir}/apache2-prefork/%{module_name}.so
|
||||
cp -a frob_sysconfig ${RPM_BUILD_ROOT}/%{my_bin_dir}
|
||||
chmod 755 ${RPM_BUILD_ROOT}/%{my_bin_dir}/frob_sysconfig
|
||||
%else
|
||||
%if %{distro} == "redhat" || %{distro} == "rhel4"
|
||||
mkdir -p ${RPM_BUILD_ROOT}/%{apache_sysconfdir}.d/
|
||||
install -m 644 %{module_name}.conf ${RPM_BUILD_ROOT}/%{apache_sysconfdir}.d/
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%clean
|
||||
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%{module_path}
|
||||
%if %{distro} == "suse"
|
||||
%dir %{my_bin_dir}
|
||||
%{my_bin_dir}/frob_sysconfig
|
||||
%{_libdir}/apache2-prefork/%{module_name}.so
|
||||
%else
|
||||
%if %{distro} == "redhat" || %{distro} == "rhel4"
|
||||
%{apache_sysconfdir}.d/%{module_name}.conf
|
||||
%endif
|
||||
%endif
|
||||
%doc COPYING.LGPL
|
||||
|
||||
%post
|
||||
%if %{distro} == "suse"
|
||||
%{my_bin_dir}/frob_sysconfig
|
||||
if [ "%{suse_version}" -lt 930 ] ; then
|
||||
/sbin/SuSEconfig --module apache2
|
||||
fi
|
||||
%endif
|
||||
|
||||
%preun
|
||||
%if %{distro} == "suse"
|
||||
if [ $1 = 0 ] ; then
|
||||
%{my_bin_dir}/frob_sysconfig --remove
|
||||
if [ "%{suse_version}" -lt 930 ] ; then
|
||||
/sbin/SuSEconfig --module apache2
|
||||
fi
|
||||
fi
|
||||
%endif
|
||||
|
||||
%triggerpostun -- mod_change_hat mod-change-hat
|
||||
%if %{distro} == "suse"
|
||||
%{my_bin_dir}/frob_sysconfig
|
||||
if [ "%{suse_version}" -lt 930 ] ; then
|
||||
/sbin/SuSEconfig --module apache2
|
||||
fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Mar 30 2006 - Seth Arnold <seth.arnold@suse.de> 2.0-7.2
|
||||
- Relicense to LGPL
|
||||
* Mon Jan 30 2006 - Steve Beattie <sbeattie@suse.de> 2.0-7.1
|
||||
- Renamed apache config options:
|
||||
ImmhatName -> AAHatName
|
||||
ImmDefaultHatName -> AADefaultHatName
|
||||
* Mon Jan 30 2006 - poeml@suse.de
|
||||
- removed libapr-util1-devel from BuildRequires (apache2-devel does
|
||||
require it)
|
||||
* Fri Jan 27 2006 Steve Beattie <sbeattie@suse.de> 2.0-6.1
|
||||
- No more neededforbuild in STABLE
|
||||
* Wed Jan 25 2006 Steve Beattie <sbeattie@suse.de> 2.0-6
|
||||
- Fix linking against libapparmor.so
|
||||
* Sun Jan 8 2006 Steve Beattie <sbeattie@suse.de> 2.0-5
|
||||
- More SUSE autobuild fixups.
|
||||
* Wed Jan 4 2006 Steve Beattie <sbeattie@suse.de> 2.0-4
|
||||
- Fixup SUSE autobuild require on apache-devel-packages
|
||||
- Add svn revision to the source tarball
|
||||
* Sun Dec 18 2005 Steve Beattie <sbeattie@novell.com> 2.0-3
|
||||
- Include symlink in %{_libdir}/apache2-prefork/
|
||||
* Thu Dec 8 2005 Steve Beattie <sbeattie@novell.com> 2.0-2
|
||||
- Rename to apache2-mod-apparmor for consistency w/SUSE packages
|
||||
- Rename module to mod_apparmor.so
|
||||
* Wed Dec 7 2005 Steve Beattie <sbeattie@novell.com> 2.0-1
|
||||
- Reset version for inclusion in SUSE autobuild
|
||||
* Mon Dec 5 2005 Steve Beattie <sbeattie@novell.com> 1.99-9
|
||||
- Rename package to mod-apparmor
|
||||
* Wed Nov 30 2005 Steve Beattie <sbeattie@novell.com> 1.99-8
|
||||
- Minor packaging cleanups
|
||||
* Wed Nov 30 2005 Steve Beattie <sbeattie@novell.com> 1.99-7_imnx
|
||||
- Convert license to GPL
|
||||
* Thu Jun 23 2005 Steve Beattie <sbeattie@novell.com> 1.99-6_imnx
|
||||
- Add trigger for mod_change_hat => mod-change-hat upgrades
|
||||
- Don't run SuSEconfig on SuSE 9.3 or newer
|
||||
* Mon May 23 2005 Steve Beattie <sbeattie@novell.com> 1.99-5_imnx
|
||||
- Fix package uninstall on RHEL4.
|
||||
* Fri Mar 11 2005 Steve Beattie <steve@immunix.com> 1.99-4_imnx
|
||||
- Rename to be consistent with other packages
|
||||
* Fri Feb 18 2005 Steve Beattie <steve@immunix.com> 1.99-3_imnx
|
||||
- Cleanup some non-64bit clean code, sigh.
|
||||
- Fix install locations on 64-bit platform.
|
||||
* Fri Feb 4 2005 Seth Arnold <sarnold@immunix.coM> 1.99-1_imnx
|
||||
- Reversion to 1.99
|
||||
* Fri Nov 12 2004 Steve Beattie <steve@immunix.com> 1.2-2_imnx
|
||||
- Add configuration file for redhat build
|
||||
* Tue Oct 12 2004 Steve Beattie <steve@immunix.com> 1.2-1_imnx
|
||||
- Bump version after shass-1.1 branched off
|
||||
* Mon Sep 20 2004 Dominic Reynolds <dominic@immunix.com> 1.0-7_imnx_(redhat|suse)
|
||||
- Modified to build separate versions for suse/redhat (EL3).
|
||||
- Note:RH version does not currently setup the module configuraiton
|
||||
- in apache.
|
||||
* Tue Aug 31 2004 Steve Beattie <steve@immunix.com> 1.0-6_imnx
|
||||
- Got location and per server config directives working somewhat
|
||||
correctly :-)
|
||||
- copyright fixups.
|
||||
* Fri Aug 20 2004 Steve Beattie <steve@immunix.com> 1.0-5_imnx
|
||||
- added support for <Location> hatname </Location>
|
||||
* Wed Jul 21 2004 Steve Beattie <steve@immunix.com> 1.0-4_imnx
|
||||
- reduced loglevel of some debug messages
|
||||
- add change_hat to list of apache modules
|
||||
* Tue Jul 20 2004 Steve Beattie <steve@immunix.com> 1.0-2_imnx
|
||||
- got module actually working, at least in simple cases.
|
||||
* Thu Jul 15 2004 Steve Beattie <steve@immunix.com> 1.0-1_imnx
|
||||
- Initial package creation.
|
76
changehat/mod_apparmor/frob_sysconfig
Executable file
|
@ -0,0 +1,76 @@
|
|||
#!/usr/bin/perl -w
|
||||
#
|
||||
# $Id: frob_sysconfig 5910 2005-12-09 03:41:29Z steve $
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2004, 2005 NOVELL (All rights reserved)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
# read /etc/sysconfig/apache2 and add "change_hat" to the apache
|
||||
# modules found there
|
||||
|
||||
use Getopt::Long;
|
||||
use File::Temp qw/ :mktemp /;
|
||||
my $module="apparmor";
|
||||
|
||||
sub usage() {
|
||||
print "$0\t--file=<file> modify <file>\n";
|
||||
print "\t\t\t--remove remove option from config file\n";
|
||||
print "\t\t\t--help this help\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
my ($conffile,$help,$remove);
|
||||
|
||||
GetOptions(
|
||||
"file=s" => \$conffile,
|
||||
"remove" => \$remove,
|
||||
"help!" => \$help
|
||||
) or usage();
|
||||
|
||||
usage() if $help;
|
||||
|
||||
if (defined $conffile) {
|
||||
$old = $conffile;
|
||||
chomp($old);
|
||||
} else {
|
||||
$old="/etc/sysconfig/apache2";
|
||||
}
|
||||
open(MENU,"<$old") or die "Fatal: can't open $old: $!";
|
||||
($fh, $file) = mkstemp($old . "XXXXXX" );
|
||||
|
||||
while (<MENU>) {
|
||||
# ok, we rely on the '="' to site the changes ;
|
||||
if (! defined $remove) {
|
||||
if ( /^\s*APACHE_MODULES="/ ) {
|
||||
if ( ! /$module/ ) {
|
||||
s/="/="$module /;
|
||||
}
|
||||
}
|
||||
} else { # remove the option
|
||||
if ( /^\s*APACHE_MODULES=".*$module/ ) {
|
||||
s/$module\s*//;
|
||||
}
|
||||
# remove old versions of the module
|
||||
if ( /^\s*APACHE_MODULES=".*change_hat/ ) {
|
||||
s/change_hat\s*//;
|
||||
}
|
||||
}
|
||||
|
||||
print $fh $_;
|
||||
}
|
||||
|
||||
rename $old, "$old.orig" || system("/bin/mv", $old, "$old.orig") &&
|
||||
die "$old could not be renamed to $old.orig ($!); see $file for modifications";
|
||||
rename $file, "$old" || system("/bin/mv", $file, "$old") &&
|
||||
die "$file could not be renamed to $old ($!); see $file for modifications";
|
360
changehat/mod_apparmor/mod_apparmor.c
Normal file
|
@ -0,0 +1,360 @@
|
|||
/* $Id: mod_apparmor.c 6354 2006-03-31 02:30:16Z sarnold $
|
||||
*
|
||||
* Copyright (c) 2004, 2005, 2006 NOVELL (All rights reserved)
|
||||
*
|
||||
* The mod_apparmor module is licensed under the terms of the GNU
|
||||
* Lesser General Public License, version 2.1. Please see the file
|
||||
* COPYING.LGPL.
|
||||
*
|
||||
* mod_apparmor - (apache 2.0.x)
|
||||
* Author: Steve Beattie <sbeattie@suse.de>
|
||||
*
|
||||
* This currently only implements change_hat functionality, but could be
|
||||
* extended for other stuff we decide to do.
|
||||
*/
|
||||
|
||||
#include "ap_config.h"
|
||||
#include "httpd.h"
|
||||
#include "http_config.h"
|
||||
#include "http_request.h"
|
||||
#include "http_log.h"
|
||||
#include "http_protocol.h"
|
||||
#include "util_filter.h"
|
||||
#include "apr.h"
|
||||
#include "apr_strings.h"
|
||||
#include "apr_lib.h"
|
||||
|
||||
#ifndef USE_COMPAT_IMMUNIX_H
|
||||
#include <sys/apparmor.h>
|
||||
#else
|
||||
#include <sys/immunix.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
/* #define DEBUG */
|
||||
#ifndef __unused
|
||||
#define __unused __attribute__((unused))
|
||||
#endif
|
||||
|
||||
/* should the following be configurable? */
|
||||
#define DEFAULT_HAT "HANDLING_UNTRUSTED_INPUT"
|
||||
#define DEFAULT_URI_HAT "DEFAULT_URI"
|
||||
|
||||
module AP_MODULE_DECLARE_DATA apparmor_module;
|
||||
|
||||
static unsigned int magic_token = 0;
|
||||
static int inside_default_hat = 0;
|
||||
|
||||
typedef struct {
|
||||
const char * hat_name;
|
||||
char * path;
|
||||
} immunix_dir_cfg;
|
||||
|
||||
typedef struct {
|
||||
const char * hat_name;
|
||||
int is_initialized;
|
||||
} immunix_srv_cfg;
|
||||
|
||||
/* immunix_init() gets invoked in the post_config stage of apache.
|
||||
* Unfortunately, apache reads its config once when it starts up, then
|
||||
* it re-reads it when goes into its restart loop, where it starts it's
|
||||
* children. This means we cannot call change_hat here, as the modules
|
||||
* memory will be wiped out, and the magic_token will be lost, so apache
|
||||
* wouldn't be able to change_hat back out. */
|
||||
static int
|
||||
immunix_init (apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
|
||||
{
|
||||
apr_file_t * file;
|
||||
apr_size_t size = sizeof (magic_token);
|
||||
int ret;
|
||||
|
||||
ret = apr_file_open (&file, "/dev/urandom", APR_READ, APR_OS_DEFAULT, p);
|
||||
if (!ret) {
|
||||
apr_file_read (file, (void *) &magic_token, &size);
|
||||
apr_file_close (file);
|
||||
} else {
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Failed to open /dev/urandom");
|
||||
}
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "Opened /dev/urandom successfully");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* As each child starts up, we'll change_hat into a default hat, mostly
|
||||
* to protect ourselves from bugs in parsing network input, but before
|
||||
* we change_hat to the uri specific hat. */
|
||||
static void
|
||||
immunix_child_init (apr_pool_t *p, server_rec *s)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "init: calling change_hat");
|
||||
ret = change_hat (DEFAULT_HAT, magic_token);
|
||||
if (ret < 0) {
|
||||
change_hat (NULL, magic_token);
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Failed to change_hat to '%s'",
|
||||
DEFAULT_HAT);
|
||||
} else {
|
||||
inside_default_hat = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
debug_dump_uri (apr_uri_t * uri)
|
||||
{
|
||||
if (uri)
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Dumping uri info "
|
||||
"scheme='%s' host='%s' path='%s' query='%s' fragment='%s'",
|
||||
uri->scheme, uri->hostname, uri->path, uri->query,
|
||||
uri->fragment);
|
||||
else
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Asked to dump NULL uri");
|
||||
|
||||
}
|
||||
#else
|
||||
static void
|
||||
debug_dump_uri (apr_uri_t * __unused uri) { }
|
||||
#endif
|
||||
|
||||
/*
|
||||
immunix_enter_hat will attempt to change_hat in the following order:
|
||||
(1) to a hatname in a location directive
|
||||
(2) to the uri
|
||||
(3) to a per-server default
|
||||
(4) to DEFAULT_URI
|
||||
(5) back to the parent profile
|
||||
*/
|
||||
static int
|
||||
immunix_enter_hat (request_rec *r)
|
||||
{
|
||||
int sd_ret = -1;
|
||||
immunix_dir_cfg * dcfg = (immunix_dir_cfg *)
|
||||
ap_get_module_config (r->per_dir_config, &apparmor_module);
|
||||
immunix_srv_cfg * scfg = (immunix_srv_cfg *)
|
||||
ap_get_module_config (r->server->module_config, &apparmor_module);
|
||||
|
||||
debug_dump_uri (&r->parsed_uri);
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_enter_hat (%s) n:0x%lx p:0x%lx main:0x%lx",
|
||||
dcfg->path, (unsigned long) r->next, (unsigned long) r->prev,
|
||||
(unsigned long) r->main);
|
||||
|
||||
/* We only call change_hat for the main request, not subrequests */
|
||||
if (r->main)
|
||||
return OK;
|
||||
|
||||
if (inside_default_hat) {
|
||||
change_hat (NULL, magic_token);
|
||||
inside_default_hat = 0;
|
||||
}
|
||||
|
||||
if (dcfg != NULL && dcfg->hat_name != NULL) {
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat [dcfg] %s", dcfg->hat_name);
|
||||
sd_ret = change_hat (dcfg->hat_name, magic_token);
|
||||
if (sd_ret < 0) {
|
||||
change_hat (NULL, magic_token);
|
||||
} else {
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat [uri] %s", r->uri);
|
||||
sd_ret = change_hat (r->uri, magic_token);
|
||||
if (sd_ret < 0) {
|
||||
change_hat (NULL, magic_token);
|
||||
} else {
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (scfg != NULL && scfg->hat_name != NULL) {
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat [scfg] %s", scfg->hat_name);
|
||||
sd_ret = change_hat (scfg->hat_name, magic_token);
|
||||
if (sd_ret < 0) {
|
||||
change_hat (NULL, magic_token);
|
||||
} else {
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat DEFAULT_URI");
|
||||
sd_ret = change_hat (DEFAULT_URI_HAT, magic_token);
|
||||
if (sd_ret < 0) change_hat (NULL, magic_token);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int
|
||||
immunix_exit_hat (request_rec *r)
|
||||
{
|
||||
int sd_ret;
|
||||
immunix_dir_cfg * dcfg = (immunix_dir_cfg *)
|
||||
ap_get_module_config (r->per_dir_config, &apparmor_module);
|
||||
/* immunix_srv_cfg * scfg = (immunix_srv_cfg *)
|
||||
ap_get_module_config (r->server->module_config, &apparmor_module); */
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "exiting change_hat - dir hat %s path %s", dcfg->hat_name, dcfg->path);
|
||||
change_hat (NULL, magic_token);
|
||||
|
||||
sd_ret = change_hat (DEFAULT_HAT, magic_token);
|
||||
if (sd_ret < 0) {
|
||||
change_hat (NULL, magic_token);
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Failed to change_hat to '%s'",
|
||||
DEFAULT_HAT);
|
||||
} else {
|
||||
inside_default_hat = 1;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static const char *
|
||||
aa_cmd_ch_path (cmd_parms * cmd, void * mconfig, const char * parm1)
|
||||
{
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "config change hat %s",
|
||||
parm1 ? parm1 : "DEFAULT");
|
||||
immunix_dir_cfg * dcfg = mconfig;
|
||||
if (parm1 != NULL) {
|
||||
dcfg->hat_name = parm1;
|
||||
} else {
|
||||
dcfg->hat_name = "DEFAULT";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int path_warn_once;
|
||||
|
||||
static const char *
|
||||
immunix_cmd_ch_path (cmd_parms * cmd, void * mconfig, const char * parm1)
|
||||
{
|
||||
if (path_warn_once == 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "ImmHatName is "
|
||||
"deprecated, please use AAHatName instead");
|
||||
path_warn_once = 1;
|
||||
}
|
||||
return aa_cmd_ch_path(cmd, mconfig, parm1);
|
||||
}
|
||||
|
||||
static const char *
|
||||
aa_cmd_ch_srv (cmd_parms * cmd, void * mconfig, const char * parm1)
|
||||
{
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "config change hat %s",
|
||||
parm1 ? parm1 : "DEFAULT");
|
||||
immunix_srv_cfg * scfg = mconfig;
|
||||
if (parm1 != NULL) {
|
||||
scfg->hat_name = parm1;
|
||||
} else {
|
||||
scfg->hat_name = "DEFAULT";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int srv_warn_once;
|
||||
|
||||
static const char *
|
||||
immunix_cmd_ch_srv (cmd_parms * cmd, void * mconfig, const char * parm1)
|
||||
{
|
||||
if (srv_warn_once == 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "ImmDefaultHatName is "
|
||||
"deprecated, please use AADefaultHatName instead");
|
||||
srv_warn_once = 1;
|
||||
}
|
||||
return aa_cmd_ch_srv(cmd, mconfig, parm1);
|
||||
}
|
||||
|
||||
static void *
|
||||
immunix_create_dir_config (apr_pool_t * p, char * path)
|
||||
{
|
||||
immunix_dir_cfg * newcfg = (immunix_dir_cfg *) apr_pcalloc(p, sizeof(* newcfg));
|
||||
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_create_dir (%s)", path ? path : ":no path:");
|
||||
if (newcfg == NULL) {
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "immunix_create_dir: couldn't alloc dir config");
|
||||
return NULL;
|
||||
}
|
||||
newcfg->path = apr_pstrdup (p, path ? path : ":no path:");
|
||||
|
||||
return newcfg;
|
||||
}
|
||||
|
||||
/* XXX: Should figure out an appropriate action to take here, if any
|
||||
|
||||
static void *
|
||||
immunix_merge_dir_config (apr_pool_t * p, void * parent, void * child)
|
||||
{
|
||||
immunix_dir_cfg * newcfg = (immunix_dir_cfg *) apr_pcalloc(p, sizeof(* newcfg));
|
||||
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_merge_dir ()");
|
||||
if (newcfg == NULL)
|
||||
return NULL;
|
||||
|
||||
return newcfg;
|
||||
}
|
||||
*/
|
||||
|
||||
static void *
|
||||
immunix_create_srv_config (apr_pool_t * p, server_rec * srv)
|
||||
{
|
||||
immunix_srv_cfg * newcfg = (immunix_srv_cfg *) apr_pcalloc(p, sizeof(* newcfg));
|
||||
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_create_srv");
|
||||
if (newcfg == NULL) {
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "immunix_create_srv: couldn't alloc srv config");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newcfg;
|
||||
}
|
||||
|
||||
|
||||
static const command_rec immunix_cmds[] = {
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"ImmHatName",
|
||||
immunix_cmd_ch_path,
|
||||
NULL,
|
||||
ACCESS_CONF,
|
||||
""
|
||||
),
|
||||
AP_INIT_TAKE1 (
|
||||
"ImmDefaultHatName",
|
||||
immunix_cmd_ch_srv,
|
||||
NULL,
|
||||
RSRC_CONF,
|
||||
""
|
||||
),
|
||||
AP_INIT_TAKE1 (
|
||||
"AAHatName",
|
||||
aa_cmd_ch_path,
|
||||
NULL,
|
||||
ACCESS_CONF,
|
||||
""
|
||||
),
|
||||
AP_INIT_TAKE1 (
|
||||
"AADefaultHatName",
|
||||
aa_cmd_ch_srv,
|
||||
NULL,
|
||||
RSRC_CONF,
|
||||
""
|
||||
),
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
register_hooks (apr_pool_t *p)
|
||||
{
|
||||
ap_hook_post_config (immunix_init, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_child_init (immunix_child_init, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_access_checker(immunix_enter_hat, NULL, NULL, APR_HOOK_FIRST);
|
||||
/* ap_hook_post_read_request(immunix_enter_hat, NULL, NULL, APR_HOOK_FIRST); */
|
||||
ap_hook_log_transaction(immunix_exit_hat, NULL, NULL, APR_HOOK_LAST);
|
||||
}
|
||||
|
||||
module AP_MODULE_DECLARE_DATA apparmor_module = {
|
||||
STANDARD20_MODULE_STUFF,
|
||||
immunix_create_dir_config, /* dir config creater */
|
||||
NULL, /* dir merger --- default is to override */
|
||||
/* immunix_merge_dir_config, */ /* dir merger --- default is to override */
|
||||
immunix_create_srv_config, /* server config */
|
||||
NULL, /* merge server config */
|
||||
immunix_cmds, /* command table */
|
||||
register_hooks /* register hooks */
|
||||
};
|
4
changehat/mod_apparmor/mod_apparmor.conf
Normal file
|
@ -0,0 +1,4 @@
|
|||
#
|
||||
# Load the Immunix SubDomain change_hat module
|
||||
#
|
||||
LoadModule apparmor_module modules/mod_apparmor.so
|
50
changehat/pam_apparmor/Makefile
Normal file
|
@ -0,0 +1,50 @@
|
|||
# $Id: Makefile 5900 2005-12-08 19:12:56Z steve $
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 1999, 2004, 2005 NOVELL (All rights reserved)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
NAME=pam_apparmor
|
||||
all:
|
||||
COMMONDIR=../../common/
|
||||
|
||||
include Make.rules
|
||||
|
||||
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
|
||||
ifeq ($(COMMONDIR_EXISTS), true)
|
||||
Make.rules: $(COMMONDIR)/Make.rules
|
||||
ln -f $(COMMONDIR)/Make.rules .
|
||||
endif
|
||||
|
||||
CFLAGS=-fPIC -shared -Xlinker -x
|
||||
LIBS=-lpam -lapparmor
|
||||
|
||||
all: $(NAME).so
|
||||
|
||||
$(NAME).so: $(NAME).c
|
||||
$(CC) $(CFLAGS) -o $@ $< $(LIBS)
|
||||
|
||||
# need some better way of determining this
|
||||
DESTDIR=/
|
||||
SECDIR=${DESTDIR}/lib/security
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
install -d 755 $(SECDIR)
|
||||
install -m 555 $(NAME).so $(SECDIR)/
|
||||
|
||||
.PHONY: clean
|
||||
clean: Make.rules
|
||||
rm -f core core.* *.so *.o *.s *.a *~
|
||||
rm -f $(TARBALL)
|
||||
|
1
changehat/pam_apparmor/README
Normal file
|
@ -0,0 +1 @@
|
|||
XXX - PUT DOCUMENTATION ABOUT PAM_APPARMOR HERE - :)
|
104
changehat/pam_apparmor/pam_apparmor.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* pam_apparmor module */
|
||||
|
||||
/*
|
||||
* Modified for pam_motd by Ben Collins <bcollins@debian.org>
|
||||
*
|
||||
* Based off of:
|
||||
* $Id: pam_motd.c,v 1.11 2005/09/21 10:01:01 t8m Exp $
|
||||
*
|
||||
* Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <security/_pam_macros.h>
|
||||
/*
|
||||
* here, we make a definition for the externally accessible function
|
||||
* in this file (this definition is required for static a module
|
||||
* but strongly encouraged generally) it is used to instruct the
|
||||
* modules include file to define the function prototypes.
|
||||
*/
|
||||
|
||||
#define PAM_SM_SESSION
|
||||
|
||||
#include <security/pam_modules.h>
|
||||
|
||||
/* --- session management functions (only) --- */
|
||||
|
||||
PAM_EXTERN int
|
||||
pam_sm_close_session (pam_handle_t *pamh, int flags,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
return PAM_IGNORE;
|
||||
}
|
||||
|
||||
PAM_EXTERN
|
||||
int pam_sm_open_session(pam_handle_t *pamh, int flags,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
int fd, retval = PAM_IGNORE;
|
||||
unsigned int magic_token = 0xDEADC0ED;
|
||||
const void *user;
|
||||
|
||||
/* grab the target user name */
|
||||
retval = pam_get_item(pamh, PAM_USER, &user);
|
||||
if (retval != PAM_SUCCESS || user == NULL || *(const char *)user == '\0') {
|
||||
return PAM_USER_UNKNOWN;
|
||||
}
|
||||
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return PAM_PERM_DENIED;
|
||||
}
|
||||
retval = read(fd, (void *) &magic_token, sizeof(magic_token));
|
||||
|
||||
close(fd);
|
||||
|
||||
/* change into the user hat */
|
||||
retval = change_hat(user, magic_token);
|
||||
if (retval < 0) {
|
||||
/* failed to change into user hat, so we'll jump back out */
|
||||
retval = change_hat(NULL, magic_token);
|
||||
if (retval == 0) {
|
||||
/* and try to change to the DEFAULT hat instead */
|
||||
retval = change_hat("DEFAULT", magic_token);
|
||||
if (retval < 0) {
|
||||
/* failed to change into default hat, so we'll
|
||||
jump back out */
|
||||
retval = change_hat(NULL, magic_token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* zero out the magic token so we can't get back out */
|
||||
memset(&magic_token, 0, sizeof(magic_token));
|
||||
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#ifdef PAM_STATIC
|
||||
|
||||
/* static module data */
|
||||
|
||||
struct pam_module _pam_apparmor_modstruct = {
|
||||
"pam_apparmor",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
pam_sm_open_session,
|
||||
pam_sm_close_session,
|
||||
NULL,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* end of module definition */
|
5
changehat/pam_apparmor/pam_apparmor.changes
Normal file
|
@ -0,0 +1,5 @@
|
|||
-------------------------------------------------------------------
|
||||
Wed Dec 21 10:31:40 PST 2005 - jmichael@suse.de
|
||||
|
||||
- initial
|
||||
|
79
changehat/pam_apparmor/pam_apparmor.spec.in
Normal file
|
@ -0,0 +1,79 @@
|
|||
#
|
||||
# spec file for package pam_apparmor (Version 2)
|
||||
#
|
||||
# Copyright (c) 2005 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
# This file and all modifications and additions to the pristine
|
||||
# package are under the same license as the package itself.
|
||||
#
|
||||
# Please submit bugfixes or comments via http://www.suse.de/feedback/
|
||||
#
|
||||
|
||||
# norootforbuild
|
||||
# neededforbuild pam-devel libapparmor
|
||||
|
||||
BuildRequires: pam-devel libapparmor
|
||||
|
||||
Name: pam_apparmor
|
||||
License: GPL
|
||||
Group: Productivity/Security
|
||||
Autoreqprov: on
|
||||
Version: @@immunix_version@@
|
||||
Release: 1
|
||||
Summary: Pam module to add AppArmor change_hat functionality
|
||||
URL: http://forge.novell.com/modules/xfmod/project/?apparmor
|
||||
Source: pam_apparmor-%{version}-@@repo_version@@.tar.gz
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
BuildRequires: pam-devel libapparmor
|
||||
Requires: pam
|
||||
Prereq: pam
|
||||
|
||||
%description
|
||||
The pam_apparmor module provides the means for any pam applications that
|
||||
call pam_open_session() to automatically perform an AppArmor change_hat
|
||||
operation in order to switch to a user-specific security policy.
|
||||
|
||||
|
||||
Authors:
|
||||
--------
|
||||
Jesse Michael jmichael@suse.de
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
make
|
||||
|
||||
%install
|
||||
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
|
||||
make install DESTDIR=${RPM_BUILD_ROOT} SECDIR=${RPM_BUILD_ROOT}/%{_lib}/security
|
||||
|
||||
%clean
|
||||
[ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT}
|
||||
|
||||
%post
|
||||
grep -qs "pam_apparmor.so" /etc/pam.d/common-session
|
||||
if [ $? != 0 ]; then
|
||||
echo "session required pam_apparmor.so" >> /etc/pam.d/common-session
|
||||
fi
|
||||
|
||||
%preun
|
||||
if [ "$1" = 0 ] ; then
|
||||
grep -qs "pam_apparmor.so" /etc/pam.d/common-session
|
||||
if [ $? == 0 ]; then
|
||||
grep -v "pam_apparmor.so" /etc/pam.d/common-session > /etc/pam.d/common-session.$$
|
||||
mv /etc/pam.d/common-session.$$ /etc/pam.d/common-session
|
||||
fi
|
||||
fi
|
||||
|
||||
%files
|
||||
%defattr(444,root,root,755)
|
||||
%doc README
|
||||
%attr(555,root,root) /%{_lib}/security/pam_apparmor.so
|
||||
|
||||
%changelog -n pam_apparmor
|
||||
* Fri Jan 13 2006 Steve Beattie <sbeattie@suse.de>
|
||||
- Add svn repo number to tarball
|
||||
* Fri Jan 13 2006 Jesse Michael <jmichael@suse.de>
|
||||
- Make magic tokens harder to guess by pulling them from /dev/urandom
|
||||
* Wed Dec 21 2005 - jmichael@suse.de
|
||||
- initial
|
129
docs/Makefile
Normal file
|
@ -0,0 +1,129 @@
|
|||
# $Id: Makefile 6225 2006-02-04 00:25:12Z steve $
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2004, 2005 NOVELL (All rights reserved)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
# stuff to make a release tarball
|
||||
NAME:=apparmor-docs
|
||||
COMMONDIR:=$(strip $(shell if [ -d "../common/" ] ; then \
|
||||
echo "../common/" ; \
|
||||
elif [ -d "../../common/" ] ; then \
|
||||
echo "../../common/" ; \
|
||||
else \
|
||||
echo "/common_dir_not_found" ; \
|
||||
fi))
|
||||
all:
|
||||
|
||||
include Make.rules
|
||||
|
||||
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
|
||||
ifeq ($(COMMONDIR_EXISTS), true)
|
||||
Make.rules: ${COMMONDIR}/Make.rules
|
||||
ln -f ${COMMONDIR}/Make.rules .
|
||||
endif
|
||||
|
||||
POD2MAN = /usr/bin/pod2man
|
||||
POD2HTML = /usr/bin/pod2html
|
||||
RELEASE_DIR = ${NAME}-${VERSION}
|
||||
MANDIRS = 2 5 7 8
|
||||
MANDIR = /usr/share/man
|
||||
DOCDIR = /usr/share/doc/${NAME}-${VERSION}
|
||||
|
||||
AA_MANPAGES = autodep.8 complain.8 enforce.8 logprof.8 genprof.8 \
|
||||
unconfined.8
|
||||
MANPAGES = change_hat.2 \
|
||||
subdomain.conf.5 apparmor.d.5 apparmor.vim.5 logprof.conf.5 \
|
||||
apparmor.7 \
|
||||
${AA_MANPAGES} \
|
||||
apparmor_parser.8 apparmor_status.8 mod_apparmor.8
|
||||
OLD_MANPAGES = subdomain.d.5 subdomain.vim.5 \
|
||||
subdomain.7 subdomain_parser.8
|
||||
DOCUMENTS = licenses/COPYING \
|
||||
licenses/Immunix_Commercial_License.html \
|
||||
licenses/Immunix_Commercial_License.txt \
|
||||
*.pdf \
|
||||
immunix.css
|
||||
PAPERS=$(wildcard papers/*)
|
||||
|
||||
HTMLMANPAGES=$(foreach manpage, ${MANPAGES}, ${manpage}.html)
|
||||
# All manpages are now autotragically generated.
|
||||
GENERATED=${MANPAGES} ${HTMLMANPAGES}
|
||||
|
||||
all: $(GENERATED)
|
||||
|
||||
help:
|
||||
@echo "This makefile is for creating a releases only."
|
||||
@echo "Please select release or rpm as targets."
|
||||
|
||||
.PHONY: release
|
||||
release: $(TARBALL)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -f $(GENERATED) $(TARBALL) $(NAME)-$(VERSION)*.tar.gz
|
||||
|
||||
# I'm pretty sure the following could be in a foreach loop, but I'm too
|
||||
# lazy to code it up.
|
||||
|
||||
%.1: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=1 > $@
|
||||
|
||||
%.2: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=2 > $@
|
||||
|
||||
%.5: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=5 > $@
|
||||
|
||||
%.7: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=7 > $@
|
||||
|
||||
%.8: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=8 > $@
|
||||
|
||||
%.1.html: %.pod
|
||||
$(POD2HTML) --header --css immunix.css --infile=$< --outfile=$@
|
||||
|
||||
%.2.html: %.pod
|
||||
$(POD2HTML) --header --css immunix.css --infile=$< --outfile=$@
|
||||
|
||||
%.5.html: %.pod
|
||||
$(POD2HTML) --header --css immunix.css --infile=$< --outfile=$@
|
||||
|
||||
%.7.html: %.pod
|
||||
$(POD2HTML) --header --css immunix.css --infile=$< --outfile=$@
|
||||
|
||||
%.8.html: %.pod
|
||||
$(POD2HTML) --header --css immunix.css --infile=$< --outfile=$@
|
||||
|
||||
.PHONY: install_manpages
|
||||
install_manpages: $(MANPAGES)
|
||||
for dir in ${MANDIRS} ; do install -d ${DESTDIR}/${MANDIR}/man$${dir} ; done
|
||||
$(foreach dir, ${MANDIRS}, \
|
||||
install -m 644 $(filter %.${dir}, ${MANPAGES}) ${DESTDIR}/${MANDIR}/man${dir}; \
|
||||
$(foreach oldpage, $(filter %.${dir}, ${OLD_MANPAGES}), \
|
||||
ln -sf $(oldpage:subdomain%=apparmor%) ${DESTDIR}/${MANDIR}/man${dir}/${oldpage};) \
|
||||
$(foreach aa_page, $(filter %.${dir}, ${AA_MANPAGES}), \
|
||||
ln -sf $(aa_page) ${DESTDIR}/${MANDIR}/man${dir}/${aa_page:%=aa-%};))
|
||||
# special case for apparmor_status
|
||||
ln -sf apparmor_status.8 ${DESTDIR}/${MANDIR}/man8/aa-status.8
|
||||
|
||||
.PHONY: install_documents
|
||||
install_documents: ${HTMLMANPAGES}
|
||||
mkdir -m 755 -p ${DESTDIR}/${DOCDIR} ${DESTDIR}/${DOCDIR}/papers
|
||||
install -m 644 $(DOCUMENTS) ${HTMLMANPAGES} ${DESTDIR}/${DOCDIR}
|
||||
install -m 644 -D ${PAPERS} ${DESTDIR}/${DOCDIR}/papers
|
||||
|
||||
.PHONY: install
|
||||
install: install_manpages install_documents
|
||||
|
BIN
docs/adv_ug_apparmor.fm
Normal file
BIN
docs/adv_ug_apparmor.pdf
Normal file
25
docs/apparmor-docs.exclude
Normal file
|
@ -0,0 +1,25 @@
|
|||
immunix.pod
|
||||
raceguard.pod
|
||||
stackguard.pod
|
||||
globber.pod
|
||||
grind.pod
|
||||
formatguard.pod
|
||||
adv_ug_apparmor.fm
|
||||
install_apparmor.fm
|
||||
install_apparmor.pdf
|
||||
theend.fm
|
||||
ug_apparmor.fm
|
||||
licenses/Immunix_Commercial_License.html
|
||||
licenses/Immunix_Commercial_License.txt
|
||||
licenses/COPYING
|
||||
papers/
|
||||
papers/discex00.pdf
|
||||
papers/discex3_autonomix_defcon.pdf
|
||||
papers/formatguard-sec01.pdf
|
||||
papers/lsm-sec02.pdf
|
||||
papers/raceguard-sec01.pdf
|
||||
papers/subdomain-lisa00.pdf
|
||||
papers/usenixsc98.pdf
|
||||
ug_apparmor.pdf
|
||||
immunizing_applications.pdf
|
||||
apparmor-docs.exclude
|
116
docs/apparmor-docs.spec.in
Normal file
|
@ -0,0 +1,116 @@
|
|||
# $Id: apparmor-docs.spec.in 6269 2006-02-16 20:29:51Z dominic $
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2004, 2005 NOVELL (All rights reserved)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
# SUSE packaging macros:
|
||||
# norootforbuild
|
||||
|
||||
# Ugh, old versions of rpm are broken wrt nested if-else statements,
|
||||
# so check first each time to see if distro is already defined.
|
||||
%if ! %{?distro:1}0
|
||||
%define distro unknown
|
||||
%endif
|
||||
|
||||
Summary: Novell AppArmor Host Application Security Suite Documentation package
|
||||
Name: apparmor-docs
|
||||
Version: @@immunix_version@@
|
||||
Release: 3.4
|
||||
Group: Applications/System
|
||||
Source0: %{name}-%{version}-@@repo_version@@.tar.gz
|
||||
License: Other License(s), see package
|
||||
BuildRoot: /var/tmp/%{name}-root
|
||||
Url: http://forge.novell.com/modules/xfmod/project/?apparmor
|
||||
Group: Applications/System
|
||||
BuildArch: noarch
|
||||
Obsoletes: subdomain-docs
|
||||
Provides: subdomain-docs
|
||||
|
||||
%description
|
||||
This package contains documentation for the AppArmor Host Application
|
||||
Security Suite.
|
||||
This package is part of a suite of tools that used to be named SubDomain.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
for file in gpl.txt lesser.txt
|
||||
do
|
||||
cp -a licenses/${file} .
|
||||
done
|
||||
|
||||
%build
|
||||
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
|
||||
make all
|
||||
|
||||
%install
|
||||
# build directories
|
||||
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
|
||||
make install_manpages DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir}
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
|
||||
# the documentation
|
||||
%{_mandir}/man2/*
|
||||
%{_mandir}/man5/*
|
||||
%{_mandir}/man7/*
|
||||
%{_mandir}/man8/*
|
||||
%doc book.apparmor.admin-online.pdf
|
||||
%doc gpl.txt
|
||||
%doc lesser.txt
|
||||
# html versions of the manpages
|
||||
%doc *.[0-9].*html
|
||||
%doc immunix.css
|
||||
|
||||
%changelog
|
||||
* Thu Feb 16 2006 Dominic Reynolds <dreynolds@suse.de> 2.0-3.4
|
||||
- Updated manual from doc group - includes new naming changes.
|
||||
* Mon Jan 30 2006 Steve Beattie <sbeattie@suse.de> 2.0-3.2
|
||||
- Add manpage for mod_apparmor
|
||||
- Update change_hat(2) manpage for renamed header/library
|
||||
- Update other documents to reflect subdomain->apparmor
|
||||
- Rename manpages, add compatibility symlinks
|
||||
* Thu Jan 5 2006 Steve Beattie <sbeattie@suse.de> 2.0-3
|
||||
- Add svn repo number to tarball
|
||||
* Thu Dec 8 2005 Dominic Reynolds <dreynolds@suse.de> 2.0-2
|
||||
- Added admin manual from documentation group, fix rpm URL
|
||||
* Wed Dec 7 2005 Steve Beattie <sbeattie@suse.de> 2.0-1
|
||||
- Reset version for inclusion in SUSE autobuild
|
||||
* Wed Nov 30 2005 Steve Beattie <sbeattie@suse.de> 1.99-8
|
||||
- Rename package to apparmor-docs
|
||||
* Mon Nov 28 2005 Seth Arnold <seth.arnold@suse.de> 1.99-7_imnx
|
||||
- keep only licenses and manpages; pdfs removed
|
||||
* Mon Jul 18 2005 Steve Beattie <sbeattie@novell.com> 1.99-6_imnx
|
||||
- Include missing pdf documents.
|
||||
* Mon Jul 11 2005 Seth Arnold <seth.arnold@suse.de> 1.99-5_imnx
|
||||
- ensure AppArmor is in all man -k listings
|
||||
* Mon Mar 28 2005 Seth Arnold <sarnold@immunix.com> 1.99-4_imnx
|
||||
- Update COPYING, include a copy of the GPL
|
||||
* Thu Mar 24 2005 Steve Beattie <steve@immunix.com> 1.99-3_imnx
|
||||
- Generate html versions of the manpages.
|
||||
* Tue Mar 9 2005 Steve Beattie <steve@immunix.com> 1.99-2_imnx
|
||||
- Update for the new location of subdomain.conf
|
||||
* Wed Feb 9 2005 Steve Beattie <steve@immunix.com> 1.99-1_imnx
|
||||
- Add a manpage for subdomain.conf
|
||||
- Reversion for 2.0 branch
|
||||
* Fri Nov 5 2004 Steve Beattie <steve@immunix.com> 1.2-3_imnx
|
||||
- whole bunch of cleanup to support building slack packages.
|
||||
* Wed Oct 13 2004 Steve Beattie <steve@immunix.com> 1.2-2_imnx
|
||||
- Minor update to change_hat manpage.
|
||||
* Tue Oct 12 2004 Steve Beattie <steve@immunix.com> 1.2-1_imnx
|
||||
- Reset version after shass-1.1 branched off
|
||||
* Tue Aug 31 2004 Steve Beattie <steve@immunix.com> 7.3-24_imnx
|
||||
- Fixup copyright statements.
|
||||
* Wed Jul 21 2004 Steve Beattie <steve@immunix.com> 7.3-23_imnx
|
||||
- add base support for cross-distro builds
|
434
docs/apparmor.d.pod
Normal file
|
@ -0,0 +1,434 @@
|
|||
# $Id: apparmor.d.pod 6225 2006-02-04 00:25:12Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
apparmor.d - syntax of security profiles for AppArmor.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
AppArmor profiles describe mandatory access rights granted to given
|
||||
programs and are fed to the AppArmor policy enforcement module using
|
||||
apparmor_parser(8). This man page describes the format of the AppArmor
|
||||
configuration files; see apparmor(7) for an overview of AppArmor.
|
||||
|
||||
=head1 FORMAT
|
||||
|
||||
The following is a BNF-style description of AppArmor policy
|
||||
configuration files; see below for an example AppArmor policy file.
|
||||
AppArmor configuration files are line-oriented; B<#> introduces a
|
||||
comment, similar to shell scripting languages. The exception to this
|
||||
rule is that B<#include> will I<include> the contents of a file inline
|
||||
to the policy; this behaviour is modelled after cpp(1).
|
||||
|
||||
=over 4
|
||||
|
||||
B<INCLUDE> = '#include' ( I<ABS PATH> | I<MAGIC PATH> )
|
||||
|
||||
B<ABS PATH> = '"' path '"' (the path is passed to open(2))
|
||||
|
||||
B<MAGIC PATH> = '<' relative path '>' (the path is relative to F</etc/apparmor.d/>)
|
||||
|
||||
B<COMMENT> = '#' I<TEXT>
|
||||
|
||||
B<TEXT> = any characters
|
||||
|
||||
B<PROFILE> = [ I<COMMENT> ... ] I<PROGRAM> [ I<flags=(complain)> ]'{' [ ( I<RESOURCE RULE> | I<COMMENT> | I<INCLUDE> ) ... ] '}' [ I<SUBPROFILE> ... ]
|
||||
|
||||
B<SUBPROFILE> = [ I<COMMENT> ... ] I<PROGRAMHAT> '{' [ ( I<FILE RULE> | I<COMMENT> | I<INCLUDE> ) ... ] '}'
|
||||
|
||||
B<PROGRAM> = (non-whitespace characters except for B<^>, must start with '/')
|
||||
|
||||
B<PROGRAMHAT> = I<PROGRAM> '^' (non-whitespace characters; see change_hat(2) for a description of how this "hat" is used.)
|
||||
|
||||
B<RESOURCE RULE> = ( I<FILE RULE> | I<NETWORK RULE> ) ','
|
||||
|
||||
B<FILE RULE> = ( I<FILENAME> | I<FILEGLOB> ) I<ACCESS>
|
||||
|
||||
B<FILENAME> = (non-whitespace characters except for B<?*[]{}^>, must start with '/')
|
||||
|
||||
B<FILEGLOB> = (non-whitespace characters, must start with '/', B<?*[]{}^> have special meanings; see below.)
|
||||
|
||||
B<ACCESS> = ( 'r' | 'w' | 'l' | 'ix' | 'ux' | 'px' ) I<ACCESS> (not all combinations are allowed; see below.)
|
||||
|
||||
=begin comment
|
||||
|
||||
XXX COMMENTED OUT UNTIL APPARMOR SUPPORTS NETDOMAIN
|
||||
|
||||
B<NETWORK RULE> = ( 'tcp_connect' | 'tcp_accept' | 'udp_send' | 'udp_receive' ) [ ( 'to' I<IP> | 'from' I<IP> ) ] [ 'via' I<IFACE> ] (Obviously, at most one 'to' and at most one 'from' is allowed per line.)
|
||||
=
|
||||
=B<IP> = I<NUM> '.' I<NUM> '.' I<NUM> '.' I<NUM> [ '/' I<NETMASK> ] [ ':' ( I<PORT> | I<PORTRANGE> ) ]
|
||||
|
||||
B<NUM> = [0-9]+
|
||||
|
||||
B<NETMASK> = I<NUM> [ I<NUM> ... ] (CIDR notation)
|
||||
|
||||
B<PORT> = I<NUM> [ I<NUM> ... ] (0-65535, inclusive)
|
||||
|
||||
B<PORTRANGE> = I<PORT> '-' I<PORT> (low port, high port, inclusive)
|
||||
|
||||
B<IFACE> = [a-z0-9]+ (name of interface; e.g., 'eth0')
|
||||
|
||||
=end comment
|
||||
|
||||
|
||||
=back
|
||||
|
||||
All resources and programs need a full path. There may be any number
|
||||
of subprofiles ("hats") in a profile, limited only by kernel memory.
|
||||
Subprofile names are limited to 974 characters. Subprofiles must be in the
|
||||
same file as the parent profile. Not all profiles benefit from subprofiles
|
||||
--- applications must either be written or modified to use change_hat(2)
|
||||
to take advantage of subprofiles. (An Apache module, mod_apparmor(5)
|
||||
has been provided to use change_hat(2).)
|
||||
|
||||
=head2 Access Modes
|
||||
|
||||
File permission access modes consists of combinations of the following
|
||||
seven modes:
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<r> - read
|
||||
|
||||
=item B<w> - write
|
||||
|
||||
=item B<px> - discrete profile execute
|
||||
|
||||
=item B<ux> - unconstrained execute
|
||||
|
||||
=item B<ix> - inherit execute
|
||||
|
||||
=item B<l> - link
|
||||
|
||||
=back
|
||||
|
||||
=head2 Access Modes Details
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<Read mode>
|
||||
|
||||
Allows the program to have read access to the resource. Read access is
|
||||
required for shell scripts and other interpreted content, and determines
|
||||
if an executing process can core dump or be attached to with ptrace(2).
|
||||
(ptrace(2) is used by utilities such as strace(1), ltrace(1), and
|
||||
gdb(1).)
|
||||
|
||||
=item B<Write mode>
|
||||
|
||||
Allows the program to have write access to the resource. Files must have
|
||||
this permission if they are to be unlinked (removed.)
|
||||
|
||||
|
||||
=item B<Unconstrained execute mode>
|
||||
|
||||
Allows the program to execute the resource without any AppArmor profile
|
||||
being applied to the executed resource. Requires listing execute mode
|
||||
as well. Incompatible with Inherit and Discrete Profile execute entries.
|
||||
|
||||
This mode is useful when a confined program needs to be able to perform
|
||||
a privileged operation, such as rebooting the machine. By placing the
|
||||
privileged section in another executable and granting unconstrained
|
||||
execution rights, it is possible to bypass the mandatory constraints
|
||||
imposed on all confined processes. For more information on what is
|
||||
constrained, see the apparmor(7) man page.
|
||||
|
||||
B<WARNING> this should only be used in very special cases. It enables the
|
||||
designated child processes to be run without any AppArmor protection.
|
||||
Use at your own risk.
|
||||
|
||||
=item B<Inherit execute mode>
|
||||
|
||||
Prevent the normal AppArmor domain transition on execve(2) when the
|
||||
profiled program executes the resource. Instead, the executed resource
|
||||
will inherit the current profile. Incompatible with Unconstrained and
|
||||
Discrete Profile execute entries.
|
||||
|
||||
This mode is useful when a confined program needs to call another
|
||||
confined program without gaining the permissions of the target's
|
||||
profile, or losing the permissions of the current profile. This mode is
|
||||
infrequently used.
|
||||
|
||||
=item B<Discrete Profile execute mode>
|
||||
|
||||
This mode requires that a discrete security profile is defined for
|
||||
a resource executed at a AppArmor domain transition. If there is no
|
||||
profile defined then the access will be denied. Incompatible with
|
||||
Inherit and Unconstrained execute entries.
|
||||
|
||||
=item B<Link mode>
|
||||
|
||||
Allows the program to be able to create and remove a link with this name
|
||||
(including symlinks). When a link is created, the file that is being
|
||||
linked to B<MUST> have the same access permissions as the link being
|
||||
created (with the exception that the destination does not have to have
|
||||
link access.) Link access is required for unlinking a file.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Comments
|
||||
|
||||
Comments start with # and may begin at any place within a line. The
|
||||
comment ends when the line ends. This is the same comment style as
|
||||
shell scripts.
|
||||
|
||||
=head2 Globbing
|
||||
|
||||
File resources may be specified with a globbing syntax similar to that
|
||||
used by popular shells, such as csh(1), bash(1), zsh(1).
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<*>
|
||||
|
||||
can substitute for any number of characters, excepting '/'
|
||||
|
||||
=item B<**>
|
||||
|
||||
can substitute for any number of characters, including '/'
|
||||
|
||||
=item B<?>
|
||||
|
||||
can substitute for any single character excepting '/'
|
||||
|
||||
=item B<[abc]>
|
||||
|
||||
will substitute for the single character a, b, or c
|
||||
|
||||
=item B<[a-c]>
|
||||
|
||||
will substitute for the single character a, b, or c
|
||||
|
||||
=item B<{ab,cd}>
|
||||
|
||||
will expand to one rule to match ab, one rule to match cd
|
||||
|
||||
=back
|
||||
|
||||
=begin comment
|
||||
|
||||
=head2 Network Rules
|
||||
|
||||
AppArmor also performs mandatory per-process mediation of network
|
||||
use, similar to tcp_wrappers (hosts_access(5)). Network access control
|
||||
is handled a little differently than file system access control ---
|
||||
a process only has network use mediated by AppArmor if there are any
|
||||
network rules in the program's profile.
|
||||
|
||||
All network rules accept specifications for a "from" address, a "to"
|
||||
address, and an interface to use. Leaving a "from" or "to" address
|
||||
unspecified is the same as using "0.0.0.0" --- a wildcard equivalent to
|
||||
INADDR_ANY. Leaving the ports unspecified for a "from" or "to" address
|
||||
is equivalent to using the range 0-65535.
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<tcp_accept>
|
||||
|
||||
is required if a program must be able to use accept(2) to
|
||||
accept an incoming TCP session setup handshake. An incoming connection
|
||||
that does not match any of the loaded rules is rejected; if no accept
|
||||
rule is loaded, the accept(2) system call is quickly rejected with
|
||||
-EACCES. If the process is allowed to perform an accept(2), rejected
|
||||
connections do NOT cause an error out of the system call --- the
|
||||
connection is simply dropped with an RST.
|
||||
|
||||
=item B<tcp_connect>
|
||||
|
||||
is required if a program must be able to use connect(2) to
|
||||
initiate an outgoing TCP session setup handshake. An outgoing connection
|
||||
that does not match any of the loaded rules is rejected with -EACCES.
|
||||
|
||||
(It is a known issue that I<tcp_connect> does not mediate TCP session
|
||||
setup when only a "via iface" is specified; read(2) and write(2)
|
||||
mediation will still occur, so explicit data transfer is impossible.)
|
||||
|
||||
=item B<udp_send>
|
||||
|
||||
is required if a program must be able to use send(2), sendto(2),
|
||||
sendmsg(2), or write(2) to communicate using a UDP socket. No outgoing
|
||||
packet is sent, and -EACCES is returned to the process.
|
||||
|
||||
(It is a known issue that I<udp_send> does not mediate outgoing UDP
|
||||
packets when only a "via iface" rule is specified. If the socket is
|
||||
connected, read(2) and write(2) mediation will still occur; however,
|
||||
explicit data transfer is possible.)
|
||||
|
||||
=item B<udp_receive>
|
||||
|
||||
is required if a program must be able to use recv(2), recvfrom(2),
|
||||
recvmsg(2), or read(2) to communicate using a UDP socket. The incoming
|
||||
packet is thrown away and no notice is sent to the communicating peer;
|
||||
if no receive rule is loaded, the system calls are quickly rejected with
|
||||
-EACCES. If the process is allowed to receive, rejected packets do NOT
|
||||
cause an error out of the system call --- the packet is simply dropped.
|
||||
|
||||
=back
|
||||
|
||||
Of special note is programs spawned by inetd(8), xinetd(8), tcpserver,
|
||||
or similar programs; as the inetd will perform an accept(2) on behalf of
|
||||
a configured service, the profile for inetd must include a I<tcp_accept>
|
||||
rule that allows connections to the service. In addition, if the program
|
||||
spawned by the inetd uses a different profile than the inetd (strongly
|
||||
recommended), then the spawned program's profile must also include a
|
||||
I<tcp_accept> or I<tcp_connect> rule, so that the short-circuit tests
|
||||
may be satisfied.
|
||||
|
||||
=end comment
|
||||
|
||||
=head2 #include mechanism
|
||||
|
||||
AppArmor provides an easy abstraction mechanism to group common file
|
||||
access requirements; this abstraction is an extremely flexible way to
|
||||
grant site-specific rights and makes writing new AppArmor profiles very
|
||||
simple by assembling the needed building blocks for any given program.
|
||||
|
||||
The use of '#include' is modelled directly after cpp(1); its use will
|
||||
replace the '#include' statement with the specified file's contents.
|
||||
B<#include "/absolute/path"> specifies that F</absolute/path> should be
|
||||
used. B<#include "relative/path"> specifies that F<relative/path> should
|
||||
be used, where the path is relative to the current working directory.
|
||||
B<#include E<lt>magic/pathE<gt>> is the most common usage; it will load
|
||||
F<magic/path> relative to a directory specified to apparmor_parser(8).
|
||||
F</etc/apparmor.d/> is the AppArmor default.
|
||||
|
||||
The supplied AppArmor profiles follow several conventions; the
|
||||
abstractions stored in F</etc/apparmor.d/abstractions/> are some
|
||||
large clusters that are used in most profiles. What follows are short
|
||||
descriptions of how some of the abstractions are used.
|
||||
|
||||
=over 4
|
||||
|
||||
=item F<abstractions/base>
|
||||
|
||||
includes files that should be readable in all profiles, files that
|
||||
should be writable in all profiles, and a single network confinement
|
||||
rule to ensure every domain includes network constraints.
|
||||
|
||||
=begin comment
|
||||
|
||||
Note: this profile set is required by programs compiled with the
|
||||
Immunix security toolchain - including StackGuard and FormatGuard.
|
||||
(Should you need to write a profile that does not include network
|
||||
rules, you may I<#include E<lt>program-chunks/base-filesE<gt>>,
|
||||
which is only the file portions of the F<abstractions/base>
|
||||
abstraction.)
|
||||
|
||||
=end comment
|
||||
|
||||
=item F<abstractions/nameservice>
|
||||
|
||||
includes file rules to allow DNS, LDAP, NIS, SMB, user and group password
|
||||
databases, services, and protocols lookups.
|
||||
|
||||
=item F<abstractions/consoles>
|
||||
|
||||
includes read and write access to the device files controlling the
|
||||
virtual console, sshd(8), xterm(1), etc. This abstraction is needed for
|
||||
many programs that interact with users.
|
||||
|
||||
=item F<abstractions/wutmp>
|
||||
|
||||
includes write access to files used to maintain wtmp(5) and utmp(5)
|
||||
databases, used with the w(1) and associated commands.
|
||||
|
||||
=item F<abstractions/kerberosclient>
|
||||
|
||||
includes file access rules needed for common kerberos clients.
|
||||
|
||||
=back
|
||||
|
||||
The abstractions stored in F</etc/apparmor.d/program-chunks/> are
|
||||
intended for use by single programs.
|
||||
|
||||
=begin comment
|
||||
|
||||
most networking rules have been
|
||||
placed in these files to facilitate better constraints. (The AppArmor
|
||||
network policies allow communication with all IP addresses, and restrict
|
||||
access to specific ports only. A system administrator may wish to allow
|
||||
certain services to communicate only with specific subnets.)
|
||||
|
||||
=end comment
|
||||
|
||||
References to user home directories in profiles are usually confined to
|
||||
abstractions stored in files with names beginning with "user-". There
|
||||
are many here suitable for customization; a few notable entries:
|
||||
|
||||
=over 4
|
||||
|
||||
=item F<program-chunks/apache-default-uri>
|
||||
|
||||
is a convenient place to put file access that should be allowed for
|
||||
Apache change_hat(2) conventions that don't have a more specific
|
||||
subprofile in Apache's profile. See also mod_apparmor(5).
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLE
|
||||
|
||||
An example AppArmor profile:
|
||||
|
||||
# a comment about foo.
|
||||
/usr/bin/foo {
|
||||
/bin/mount ux,
|
||||
/dev/{,u}random r,
|
||||
/etc/ld.so.cache r,
|
||||
/etc/foo.conf r,
|
||||
/etc/foo/* r,
|
||||
/lib/ld-*.so* x,
|
||||
/lib/lib*.so* r,
|
||||
/proc/[0-9]** r,
|
||||
/usr/lib/** r,
|
||||
/tmp/foo.pid wr,
|
||||
/tmp/foo.* lrw,
|
||||
|
||||
# a comment about foo's subprofile, bar.
|
||||
^bar {
|
||||
/lib/ld-*.so* x,
|
||||
/usr/bin/bar x,
|
||||
/var/spool/* rwl,
|
||||
}
|
||||
}
|
||||
|
||||
=head1 FILES
|
||||
|
||||
=over 4
|
||||
|
||||
=item F</etc/init.d/boot.apparmor>
|
||||
|
||||
=item F</etc/apparmor.d/>
|
||||
|
||||
=item F</usr/share/vim/current/syntax/apparmor.vim>
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor_parser(8), complain(1),
|
||||
enforce(1), change_hat(2), mod_apparmor(5), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
154
docs/apparmor.pod
Normal file
|
@ -0,0 +1,154 @@
|
|||
# $Id: apparmor.pod 6226 2006-02-04 00:29:34Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
AppArmor kernel enhancement to confine programs to a limited set of resources.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
AppArmor is a kernel enhancement to confine programs to a limited set
|
||||
of resources. AppArmor's unique security model is to bind access control
|
||||
attributes to programs rather than to users.
|
||||
|
||||
AppArmor confinement is provided via I<profiles> loaded into the kernel
|
||||
via apparmor_parser(8), typically through the F</etc/init.d/boot.apparmor>
|
||||
SysV initscript, which is used like this:
|
||||
|
||||
# /etc/init.d/boot.apparmor start
|
||||
# /etc/init.d/boot.apparmor stop
|
||||
# /etc/init.d/boot.apparmor restart
|
||||
# /etc/init.d/boot.apparmor kill
|
||||
|
||||
AppArmor can operate in two modes: I<enforcement>, and I<complain or learning>:
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
I<enforcement> - Profiles loaded in enforcement mode will result
|
||||
in enforcement of the policy defined in the profile as well as reporting
|
||||
policy violation attempts to syslogd.
|
||||
|
||||
=item *
|
||||
|
||||
I<complain> - Profiles loaded in C<complain> mode will not enforce policy.
|
||||
Instead, it will report policy violation attempts. This mode is convenient for
|
||||
developing profiles. To manage complain mode for individual profiles the
|
||||
utilities /usr/bin/complain and /usr/bin/enforce can be used.
|
||||
These utilities take a program name as an argument.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
Profiles are traditionally stored in files in F</etc/apparmor.d/>
|
||||
under filenames with the convention of replacing the B</> in pathnames
|
||||
with B<.> (except for the root B</>) so profiles are easier to manage
|
||||
(e.g. the F</usr/sbin/sshd> profile would be named F<usr.sbin.sshd>).
|
||||
|
||||
Profiles are applied to a process at exec(3) time (as seen through the
|
||||
execve(2) system call); an already running process cannot be confined.
|
||||
However, once a profile is loaded for a program, that program will be
|
||||
confined on the next exec(3).
|
||||
|
||||
AppArmor supports the Linux kernel's securityfs filesystem, and makes
|
||||
available the list of the profiles currently loaded; to mount the
|
||||
filesystem:
|
||||
|
||||
# mount -tsecurityfs securityfs /sys/kernel/security
|
||||
$ cat /sys/kernel/security/apparmor/profiles
|
||||
/usr/bin/mutt
|
||||
/usr/bin/gpg
|
||||
...
|
||||
|
||||
Normally, the initscript will mount securityfs if it has not already
|
||||
been done.
|
||||
|
||||
AppArmor also restricts what privileged operations a confined process
|
||||
may execute, even if the process is running as root. A confined process
|
||||
cannot call the following system calls:
|
||||
|
||||
create_module(2) delete_module(2) init_module(2) ioperm(2)
|
||||
iopl(2) mount(2) umount(2) ptrace(2) reboot(2) setdomainname(2)
|
||||
sethostname(2) swapoff(2) swapon(2) sysctl(2)
|
||||
|
||||
A confined process can not call mknod(2) to create character or block devices.
|
||||
|
||||
=head1 ERRORS
|
||||
|
||||
When a confined process tries to access a file it does not have permission
|
||||
to access, the kernel will report a message to klogd, similar to:
|
||||
|
||||
AppArmor: REJECTING x access to /bin/bash (irssi(2667)
|
||||
profile /usr/local/bin/irssi active /usr/local/bin/irssi)
|
||||
AppArmor: REJECTING r access to /home/sarnold (mozilla-bin(3029)
|
||||
profile /usr/lib/mozilla-1.4/mozilla-bin active
|
||||
/usr/lib/mozilla-1.4/mozilla-bin)
|
||||
AppArmor: REJECTING rw access to /dev/pts/4 (sh(1721)
|
||||
profile /usr/bin/crontab active /usr/bin/crontab)
|
||||
|
||||
The permissions requested by the process are immediately after
|
||||
REJECTING. The "name" and process id of the running program are reported,
|
||||
as well as the profile name and any "hat" that may be active. ("Name"
|
||||
is in quotes, because the process name is limited to 15 bytes; it is the
|
||||
same as reported through the Berkeley process accounting.) If no hat is
|
||||
active (see change_hat(2)) then the profile name is printed for "active".
|
||||
|
||||
For confined processes running under a profile that has been loaded in
|
||||
complain mode, enforcement will not take place and the log messages
|
||||
reported to klogd will be of the form:
|
||||
|
||||
AppArmor: PERMITTING r access to /root/.viminfo (vi(1272)
|
||||
profile /bin/vim active /bin/vim)
|
||||
AppArmor: PERMITTING w access to /root/.viminfo.tmp (vi(1272)
|
||||
profile /bin/vim active /bin/vim)
|
||||
AppArmor: PERMITTING wl access to /root/.viminfo (vi(1272)
|
||||
profile /bin/vim active /bin/vim)
|
||||
AppArmor: PERMITTING rwl access to /root/.viminfo.tmp (vi(1272)
|
||||
profile /bin/vim active /bin/vim)
|
||||
AppArmor: PERMITTING w access to /root/.viminfo (vi(1272)
|
||||
profile /bin/vim active /bin/vim)
|
||||
|
||||
=head1 FILES
|
||||
|
||||
=over 4
|
||||
|
||||
=item F</etc/init.d/boot.apparmor>
|
||||
|
||||
=item F</etc/apparmor.d/>
|
||||
|
||||
=item F</usr/share/vim/current/syntax/apparmor.vim>
|
||||
|
||||
=item F</lib/apparmor/>
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor_parser(8), change_hat(2), apparmor.d(5),
|
||||
subdomain.conf(5), autodep(1), clean(1), apparmor.vim(5),
|
||||
unconfined(8), enforce(1), complain(1), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
69
docs/apparmor.vim.pod
Normal file
|
@ -0,0 +1,69 @@
|
|||
# $Id: apparmor.vim.pod 6225 2006-02-04 00:25:12Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
apparmor.vim - vim syntax highlighting file for AppArmor profiles
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
To automatically use the apparmor.vim syntax highlighting in vim, place
|
||||
the following lines in your ~/.vimrc file:
|
||||
|
||||
autocmd BufNewFile,BufRead /etc/apparmor.d/* set syntax=apparmor
|
||||
autocmd BufNewFile,BufRead */sdprofiles/* set syntax=apparmor
|
||||
autocmd BufNewFile,BufRead */codomain-*/*/* set syntax=apparmor
|
||||
|
||||
syntax on
|
||||
|
||||
If you wish to use the profile in a specific vim session, you may run:
|
||||
|
||||
:syntax on
|
||||
:set syntax=apparmor
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<apparmor.vim> provides syntax highlighting rules for the vim(1) text
|
||||
editor; the rules provide an easy visual method to inspect AppArmor
|
||||
profiles for syntax correctness and semantics.
|
||||
|
||||
The most useful colors provided are I<red> for C<unconstrained execute>
|
||||
access, I<green> for C<execute> access, and I<yellow> for C<write> access.
|
||||
|
||||
=head1 FILES
|
||||
|
||||
F</usr/share/vim/current/syntax/apparmor.vim>
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
B<apparmor.vim> does not currently parse correctly files that are
|
||||
#include'd or hats (see change_hat(2)). Patches accepted. If you find
|
||||
any bugs, please report them to bugzilla at L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
vim(1), apparmor(7), apparmor.d(5), change_hat(2), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>
|
||||
|
||||
=cut
|
114
docs/apparmor_parser.pod
Normal file
|
@ -0,0 +1,114 @@
|
|||
# $Id: apparmor_parser.pod 6225 2006-02-04 00:25:12Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
apparmor_parser - loads AppArmor profiles into the kernel
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<apparmor_parser [-adrR] [--add] [--debug] [--replace] [--remove]
|
||||
[--preprocess] [--Include n] [--base n] [ --Complain ]>
|
||||
|
||||
B<apparmor_parser [-hv] [--help] [--version]>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<apparmor_parser> is used to import new apparmor.d(5) profiles
|
||||
into the Linux kernel. The profiles restrict the operations available
|
||||
to processes by executable name.
|
||||
|
||||
The profiles are loaded into the Linux kernel by the B<apparmor_parser>
|
||||
program, which takes its input from standard input. The input supplied to
|
||||
B<apparmor_parser> should be in the format described in apparmor.d(5).
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 4
|
||||
|
||||
=item -a, --add
|
||||
|
||||
Insert the AppArmor definitions given into the kernel. This is the default
|
||||
action. This gives an error message if a AppArmor definition by the same
|
||||
name already exists in the kernel, or if the parser doesn't understand
|
||||
its input. It reports when an addition succeeded.
|
||||
|
||||
=item -r, --replace
|
||||
|
||||
This flag is required if an AppArmor definition by the same name already
|
||||
exists in the kernel, and one wants to replace the definition already
|
||||
in the kernel with the definition giving on standard input.
|
||||
|
||||
=item -R, --remove
|
||||
|
||||
This flag is used to remove an AppArmor definition already in the kernel.
|
||||
Note that it still requires a complete AppArmor definition as described
|
||||
in subdomain.d(5) even though the contents of the definition aren't
|
||||
used.
|
||||
|
||||
=item -p, --preprocess
|
||||
|
||||
Parse the profile(s) and process include directives and output the
|
||||
result to stdout.
|
||||
|
||||
=item -I n, --Include n
|
||||
|
||||
Add element n to the search path when resolving #include directives
|
||||
defined as an absolute paths.
|
||||
|
||||
=item -b n, --base n
|
||||
|
||||
Set the base directory for resolving #include directives
|
||||
defined as relative paths.
|
||||
|
||||
=item -C, --Complain
|
||||
|
||||
Load the profile in complain mode.
|
||||
|
||||
=item -h, --help
|
||||
|
||||
Give a quick reference guide.
|
||||
|
||||
=item -v, --version
|
||||
|
||||
Print the version number and exit.
|
||||
|
||||
=item -d, --debug
|
||||
|
||||
Given once, only checks the profiles to ensure syntactic correctness.
|
||||
Given twice, dumps its interpretation of the profile for checking.
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None known. If you find any, please report them to bugzilla at
|
||||
L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor.d(5), subdomain.conf(5), change_hat(2), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
100
docs/apparmor_status.pod
Normal file
|
@ -0,0 +1,100 @@
|
|||
# $Id: apparmor_status.pod 6225 2006-02-04 00:25:12Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
apparmor_status - display various information about the current AppArmor
|
||||
policy.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<apparmor_status> [option]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<apparmor_status> will report various aspects of the current state of
|
||||
AppArmor confinement. By default, it displays the same information as if
|
||||
the I<--verbose> argument were given. A sample of what this looks like
|
||||
is:
|
||||
|
||||
apparmor module is loaded.
|
||||
110 profiles are loaded.
|
||||
102 profiles are in enforce mode.
|
||||
8 profiles are in complain mode.
|
||||
Out of 129 processes running:
|
||||
13 processes have profiles defined.
|
||||
8 processes have profiles in enforce mode.
|
||||
5 processes have profiles in complain mode.
|
||||
|
||||
Other argument options are provided to report individual aspects, to
|
||||
support being used in scripts.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
B<apparmor_status> accepts only one argument at a time out of:
|
||||
|
||||
=over 4
|
||||
|
||||
=item --enabled
|
||||
|
||||
returns error code if AppArmor is not enabled.
|
||||
|
||||
=item --profiled
|
||||
|
||||
displays the number of loaded AppArmor policies.
|
||||
|
||||
=item --enforced
|
||||
|
||||
displays the number of loaded enforcing AppArmor policies.
|
||||
|
||||
=item --complaining
|
||||
|
||||
displays the number of loaded non-enforcing AppArmor policies.
|
||||
|
||||
=item --verbose
|
||||
|
||||
displays multiple data points about loaded AppArmor policy
|
||||
set (the default action if no arguments are given).
|
||||
|
||||
=item --help
|
||||
|
||||
displays a short usage statement.
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
B<apparmor_status> must be run as root to read the state of the loaded
|
||||
policy from the apparmor module. It uses the /proc filesystem to determine
|
||||
which processes are confined and so is susceptible to race conditions.
|
||||
|
||||
If you find any additional bugs, please report them to bugzilla at
|
||||
L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor.d(5), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
53
docs/autodep.pod
Normal file
|
@ -0,0 +1,53 @@
|
|||
# $Id: autodep.pod 6203 2006-02-02 22:03:41Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
autodep - guess basic AppArmor profile requirements
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<autodep I<E<lt>executableE<gt>> [I<E<lt>executableE<gt>> ...]>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<autodep> is used to generate a minimal AppArmor profile for a set of
|
||||
executables. This program will generate a profile for binary executable
|
||||
as well as interpreted script programs. At a minimum autodep will provide
|
||||
a base profile containing a base include directive which includes basic
|
||||
profile entries needed by most programs. The profile is generated by
|
||||
recursively calling ldd(1) on the executables listed on the command line.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
This program does not perform full static analysis of executables, so
|
||||
the profiles generated are necessarily incomplete. If you find any bugs,
|
||||
please report them to bugzilla at L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor.d(5), complain(1), enforce(1), change_hat(2), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
BIN
docs/book.apparmor.admin-online.pdf
Normal file
222
docs/change_hat.pod
Normal file
|
@ -0,0 +1,222 @@
|
|||
# $Id: change_hat.pod 6203 2006-02-02 22:03:41Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
change_hat - change to or from a "hat" within a AppArmor profile
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<#include E<lt>sys/apparmor.hE<gt>>
|
||||
|
||||
B<int change_hat (char *subprofile, unsigned int magic_token);>
|
||||
|
||||
Link with B<-lapparmor> when compiling.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
An AppArmor profile applies to an executable program; if a portion of
|
||||
the program needs different access permissions than other portions,
|
||||
the program can "change hats" to a different role, also known as a
|
||||
subprofile. To change into a new hat, it calls the change_hat() function
|
||||
to do so. It passes in a pointer to the I<subprofile> which it wants to
|
||||
change into, and a 32bit I<magic_token>. The I<magic_token> is used to
|
||||
return out of the subprofile at a later time.
|
||||
|
||||
If a program wants to return out of the current subprofile to the
|
||||
original profile, it calls change_hat() with a pointer to NULL as
|
||||
the I<subprofile>, and the original I<magic_token> value. If the
|
||||
I<magic_token> does not match the original I<magic_token> passed into the
|
||||
kernel when the program entered the subprofile, the change back to the
|
||||
original profile will not happen, and the current task will be killed.
|
||||
If the I<magic_token> matches the original token, then the process will
|
||||
change back to the original profile.
|
||||
|
||||
If the program wants to change to a subprofile that it can never
|
||||
change back out of, the application should call change_hat() with a
|
||||
I<magic_token> of I<0>.
|
||||
|
||||
As both read(2) and write(2) are mediated, a file must be listed in a
|
||||
subprofile definition if the file is to be accessed while the process
|
||||
is in a "hat".
|
||||
|
||||
=head1 RETURN VALUE
|
||||
|
||||
On success zero is returned. On error, -1 is returned, and
|
||||
errno(3) is set appropriately.
|
||||
|
||||
=head1 ERRORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<ENOMEM>
|
||||
|
||||
Insufficient kernel memory was available.
|
||||
|
||||
=item B<EACCES>
|
||||
|
||||
The I<magic_token> passed in was 0, which is not a valid value for
|
||||
the I<magic_token>, or the specified I<subprofile> does not exist in
|
||||
this profile.
|
||||
|
||||
=item B<EFAULT>
|
||||
|
||||
An internal error occurred.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLE
|
||||
|
||||
The following code examples shows simple, if contrived, uses of
|
||||
change_hat(); a typical use of change_hat() will separate privileged
|
||||
portions of a process from unprivileged portions of a process, such as
|
||||
keeping unauthenticated network traffic handling separate from
|
||||
authenticated network traffic handling in OpenSSH or executing
|
||||
user-supplied CGI scripts in apache.
|
||||
|
||||
The use of random(3) is simply illustrative. Use of F</dev/urandom> is
|
||||
recommended.
|
||||
|
||||
First, a simple high-level overview of change_hat() use:
|
||||
|
||||
void foo (void) {
|
||||
int magic_token;
|
||||
|
||||
/* get a random magic token value
|
||||
from our huge entropy pool */
|
||||
magic_token = random_function();
|
||||
|
||||
/* change into the subprofile while
|
||||
* we do stuff we don't trust */
|
||||
change_hat ("stuff_we_dont_trust", magic_token);
|
||||
|
||||
/* Go do stuff we don't trust -- this is all
|
||||
* done in *this* process space, no separate
|
||||
* fork()/exec()'s are done. */
|
||||
interpret_perl_stuff(stuff_from_user);
|
||||
|
||||
/* now change back to our original profile */
|
||||
change_hat (NULL, magic_token);
|
||||
}
|
||||
|
||||
Second, an example to show that files not listed in a subprofile
|
||||
("hat") aren't accessible after a change_hat() call:
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/apparmor.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int fd;
|
||||
int tok;
|
||||
char buf[10];
|
||||
|
||||
/* random() is a poor choice */
|
||||
tok = random();
|
||||
|
||||
/* open /etc/passwd outside of any hat */
|
||||
if ((fd=open("/etc/passwd", O_RDONLY)) < 0)
|
||||
perror("Failure opening /etc/passwd");
|
||||
|
||||
/* confirm for ourselves that we can really read /etc/passwd */
|
||||
memset(&buf, 0, 10);
|
||||
if (read(fd, &buf, 10) == -1) {
|
||||
perror("Failure reading /etc/passwd pre-hat");
|
||||
_exit(1);
|
||||
}
|
||||
buf[9] = '\0';
|
||||
printf("/etc/passwd: %s\n", buf);
|
||||
|
||||
/* change hat to the "hat" subprofile, which should not have
|
||||
* read access to /etc/passwd -- even though we have a valid
|
||||
* file descriptor at the time of the change_hat() call. */
|
||||
if (change_hat("hat", tok)) {
|
||||
perror("Failure changing hat -- aborting");
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
/* confirm that we cannot read /etc/passwd */
|
||||
lseek(fd,0,SEEK_SET);
|
||||
memset(&buf, 0, 10);
|
||||
if (read(fd, &buf, 10) == -1)
|
||||
perror("Failure reading /etc/passwd post-hat");
|
||||
buf[9] = '\0';
|
||||
printf("/etc/passwd: %s\n", buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
This code example requires the following profile to be loaded with
|
||||
apparmor_parser(8):
|
||||
|
||||
/tmp/ch {
|
||||
#default entries; most required by __canary_death_handler()
|
||||
/dev/log w ,
|
||||
/etc/ld.so.cache r ,
|
||||
/etc/locale/** r ,
|
||||
/etc/localtime r ,
|
||||
/usr/share/locale/** r ,
|
||||
/usr/share/zoneinfo/** r ,
|
||||
/usr/lib/locale/** r ,
|
||||
/usr/lib/gconv/*.so r ,
|
||||
/usr/lib/gconv/gconv-modules* r ,
|
||||
#entries specific to this application
|
||||
/lib/ld-*.so* rx ,
|
||||
/lib/libc*.so* r ,
|
||||
/etc/passwd r ,
|
||||
/dev/pts/* rw,
|
||||
/tmp/ch r ,
|
||||
}
|
||||
|
||||
/tmp/ch^hat {
|
||||
/dev/pts/* rw,
|
||||
}
|
||||
|
||||
The output when run:
|
||||
|
||||
$ /tmp/ch
|
||||
/etc/passwd: root:x:0:
|
||||
Failure reading /etc/passwd post-hat: Permission denied
|
||||
/etc/passwd:
|
||||
$
|
||||
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None known. If you find any, please report them to bugzilla at
|
||||
L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor.d(5), apparmor_parser(8), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
49
docs/complain.pod
Normal file
|
@ -0,0 +1,49 @@
|
|||
# $Id: complain.pod 6203 2006-02-02 22:03:41Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
complain - set a AppArmor security profile to I<complain> mode.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<complain I<E<lt>executableE<gt>> [I<E<lt>executableE<gt>> ...]>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<complain> is used to set the enforcement mode for one or more profiles to complain.
|
||||
In this mode security policy is not enforced but rather access violations are logged
|
||||
to the system log.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None. Please report any you find to bugzilla at
|
||||
L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor.d(5), enforce(1), change_hat(2), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
52
docs/enforce.pod
Normal file
|
@ -0,0 +1,52 @@
|
|||
# $Id: enforce.pod 6203 2006-02-02 22:03:41Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
enforce - set an AppArmor security profile to I<enforce> mode from
|
||||
I<complain> mode.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<enforce I<E<lt>executableE<gt>> [I<E<lt>executableE<gt>> ...]>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<enforce> is used to set the enforcement mode for one or more profiles
|
||||
to I<enforce>. This command is only relevant is conjuction with the
|
||||
utility I<complain> which sets a profile to complain mode. The default
|
||||
mode for a security policy is enforce and the I<complain> utility must
|
||||
be run to change this behavior.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None. Please report any you find to bugzilla at
|
||||
L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor.d(5), complain(1), change_hat(2), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
87
docs/genprof.pod
Normal file
|
@ -0,0 +1,87 @@
|
|||
# $Id: genprof.pod 6203 2006-02-02 22:03:41Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
genprof - profile generation utility for AppArmor
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<genprof I<E<lt>executableE<gt>> [I<-d /path/to/profiles>]>
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
B<-d --dir /path/to/profiles>
|
||||
|
||||
Specifies where to look for the AppArmor security profile set.
|
||||
Defaults to /etc/apparmor.d.
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
When running genprof, you must specify a program to profile. If the
|
||||
specified program is not a fully-qualified path, genprof will search $PATH
|
||||
in order to find the program.
|
||||
|
||||
If a profile does not exist for the program, genprof will create one using
|
||||
autodep(1).
|
||||
|
||||
Genprof will then:
|
||||
|
||||
- set the profile to complain mode
|
||||
|
||||
- write a mark to the system log
|
||||
|
||||
- instruct the user to start the application to
|
||||
|
||||
be profiled in another window and exercise its functionality
|
||||
|
||||
It then presents the user with two options, (S)can system log for entries
|
||||
to add to profile and (D)one.
|
||||
|
||||
If the user selects (S)can or hits return, genprof will parse
|
||||
the complain mode logs and iterate through generated violations
|
||||
using logprof(1).
|
||||
|
||||
After the user finishes selecting profile entries based on violations
|
||||
that were detected during the program execution, genprof will reload
|
||||
the updated profiles in complain mode and again prompt the user for (S)can and
|
||||
(D)one. This cycle can then be repeated as neccesary until all application
|
||||
functionality has been exercised without generating access violations.
|
||||
|
||||
When the user eventually hits (D)one, genprof will set the main profile,
|
||||
and any other profiles that were generated, into enforce mode and exit.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None. Please report any you find to bugzilla at
|
||||
L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor.d(5), enforce(1), complain(1), change_hat(2),
|
||||
logprof(1), logprof.conf(5), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
30
docs/immunix.css
Normal file
|
@ -0,0 +1,30 @@
|
|||
BODY {background:rgb(000,000,000); color:rgb(225,225,225);
|
||||
margin-left: 1%; margin-right: 5%}
|
||||
H1 {color:rgb(240,240,240); font-size:115%;}
|
||||
H2 {color:rgb(240,240,240); font-size:109%;}
|
||||
H3 {color:rgb(240,240,240); font-size:104%;}
|
||||
TD.sidebar {width:18em; background:rgb(020,020,020); vertical-align:top;}
|
||||
TD.main {width:250em; background:rgb(020,020,020); padding-top:5px;
|
||||
padding-bottom:5px; padding-left:10px; padding-right:10px; }
|
||||
TD.sidebarhead {background:rgb(038,038,038);}
|
||||
TD.footer {background:rgb(020,020,020); padding:5px; }
|
||||
TD.block {background: #9c9c9c; color:rgb(000,000,000)}
|
||||
|
||||
P {font-size:102%}
|
||||
P {margin-left:.5em; margin-right:.5em}
|
||||
P {color:rgb(225,225,225)}
|
||||
|
||||
P.sidebar {font-size:98% }
|
||||
P.sidebarhead {font-size:98%; font-weight:bold; }
|
||||
|
||||
UL {font-size:102%}
|
||||
UL {margin-left:.5em; margin-right:.5em}
|
||||
UL {color:rgb(225,225,225)}
|
||||
|
||||
IMG {border:none}
|
||||
|
||||
:link, :visited, :active { text-decoration:underline; }
|
||||
|
||||
:link { color: white }
|
||||
:visited { color: rgb(225,225,225)}
|
||||
:active { color: gray }
|
80
docs/immunix.pod
Normal file
|
@ -0,0 +1,80 @@
|
|||
# $Id: immunix.pod 5820 2005-11-30 19:51:33Z sarnold $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Immunix - an introduction to Immunix technologies
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
AppArmor is designed to increase the security of a typical Linux system
|
||||
without noticeable impact on users of the system.
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
SubDomain provides a filesystem-based process confinement mechanism; it
|
||||
also mediates many system calls to prevent confined root-level
|
||||
processes from breaking out of their domains.
|
||||
|
||||
=back
|
||||
|
||||
=head1 USER GUIDE
|
||||
|
||||
A comprehensive discussion of AppArmor technologies is included in the User's Guide,
|
||||
available in F</usr/share/doc/packages/subdomain-docs/immunizing_applications.pdf>.
|
||||
|
||||
|
||||
=head1 CONTRIBUTED SOFTWARE
|
||||
|
||||
Immunix, Inc., provides additional software for AppArmor
|
||||
in the /extras directory F</usr/src/kernel-modules/SubDomain/profiles/extras>.
|
||||
This extra software includes SubDomain
|
||||
profiles and rpms containing "change-hat" enabled versions of software.
|
||||
Immunix does not provide support for software located in this directory.
|
||||
If you would like to contribute Immunized software packages, please send
|
||||
mail to the immunix-users mail list. (See below.)
|
||||
|
||||
|
||||
=head1 FEEDBACK
|
||||
|
||||
Please file bug reports at L<https://bugs.wirex.com>. We also
|
||||
have two mail lists: a moderate traffic immunix-users mail list
|
||||
(L<http://mail.wirex.com/mailman/listinfo/immunix-users/>) used for
|
||||
discussion with other Immunix OS users and a low traffic immunix-announce
|
||||
(L<http://mail.wirex.com/mailman/listinfo/immunix-announce/>) mail list
|
||||
used for security update and new product announcements.
|
||||
|
||||
Security bugs may be reported directly to security@immunix.com;
|
||||
Immunix, Inc., recommends bug reporters follow the RFPolicy
|
||||
(L<http://www.wiretrip.net/rfp/policy.html>) when reporting
|
||||
vulnerabilities.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
subdomain(7),
|
||||
F</usr/share/doc/packages/subdomain-docs/immunizing_applications.pdf>
|
||||
|
||||
=cut
|
||||
subdomain(7)
|
||||
|
||||
=cut
|
BIN
docs/immunizing_applications.pdf
Normal file
BIN
docs/install_apparmor.fm
Normal file
BIN
docs/install_apparmor.pdf
Normal file
116
docs/logprof.conf.pod
Normal file
|
@ -0,0 +1,116 @@
|
|||
# $Id: logprof.conf.pod 6203 2006-02-02 22:03:41Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
logprof.conf - configuration file for expert options that modify the
|
||||
behavior of the AppArmor logprof(1) program.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The logprof(1) program can be configured to have certain default behavior
|
||||
by the contents of logprof.conf.
|
||||
|
||||
The B<[qualifiers]> section lists specific programs that should have
|
||||
a subset of the full ix/px/ux list when asking what mode to execute
|
||||
it using.
|
||||
|
||||
Since creating a separate profile for /bin/bash is dangerous, we can
|
||||
specify that for /bin/bash, only (I)nherit, (U)nconstrained, and (D)eny
|
||||
should be allowed options and only those will show up in the prompt when
|
||||
we're asking about adding that to a profile.
|
||||
|
||||
Likewise, if someone currently exec's /bin/mount in ix or px mode, things
|
||||
won't work, so we can provide only (U)nconstrained and (D)eny as options.
|
||||
|
||||
And certain apps like grep, awk, sed, cp, and mkdir should always
|
||||
inherit the parent profile rather than having their own profile or
|
||||
running unconfined, so for them we can specify that only (I)nherit and
|
||||
(D)eny are the allowed options.
|
||||
|
||||
Any programs that are not listed in the qualifiers section get the full
|
||||
(I)nherit / (P)rofile / (U)nconstrained / (D)eny option set.
|
||||
|
||||
If the user is doing something tricky and wants different behavior,
|
||||
they can tweak or remove the corresponding line in the conf file.
|
||||
|
||||
The B<[defaulthat]> section lists changehat-aware programs and what hat
|
||||
logprof(1) will collapse the entries to for that program if the user
|
||||
specifies that the access should be allowed, but should not have it's
|
||||
own hat.
|
||||
|
||||
The B<[globs]> section allows modification of the logprof rule engine
|
||||
with respect to globbing suggestions that the user will be prompted with.
|
||||
|
||||
The format of each line is-- "<perl glob> = <apparmor glob>".
|
||||
|
||||
When logprof(1) asks about a specific path, if the perl glob matches the
|
||||
path, it replaces the part of the path that matched with the corresponding
|
||||
apparmor glob and adds it to the list of globbing suggestions.
|
||||
|
||||
Lines starting with # are comments and are ignored.
|
||||
|
||||
=head1 EXAMPLE
|
||||
|
||||
[qualifiers]
|
||||
# things will very likely be painfully broken if bash has it's own profile
|
||||
/bin/bash = iu
|
||||
|
||||
# mount doesn't work if it's confined
|
||||
/bin/mount = u
|
||||
|
||||
# these helper utilities should inherit the parent profile and
|
||||
# shouldn't have their own profiles
|
||||
/bin/awk = i
|
||||
/bin/grep = i
|
||||
/bin/sed = i
|
||||
|
||||
[defaulthat]
|
||||
/usr/sbin/sshd = EXEC
|
||||
/usr/sbin/httpd2 = DEFAULT_URI
|
||||
/usr/sbin/httpd2-prefork = DEFAULT_URI
|
||||
|
||||
[globs]
|
||||
# /foo/bar/lib/libbaz.so -> /foo/bar/lib/lib*
|
||||
/lib/lib[^\/]+so[^\/]*$ = /lib/lib*so*
|
||||
|
||||
# strip kernel version numbers from kernel module accesses
|
||||
^/lib/modules/[^\/]+\/ = /lib/modules/*/
|
||||
|
||||
# strip pid numbers from /proc accesses
|
||||
^/proc/\d+/ = /proc/*/
|
||||
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None. Please report any you find to bugzilla at
|
||||
L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor.d(5), enforce(1), change_hat(2),
|
||||
complain(1), logprof(1), genprof(1), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
168
docs/logprof.pod
Normal file
|
@ -0,0 +1,168 @@
|
|||
# $Id: logprof.pod 6203 2006-02-02 22:03:41Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
logprof - utility program for managing AppArmor security profiles
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<logprof [I<-d /path/to/profiles>] [I<-f /path/to/logfile>] [I<-m E<lt>mark in logfileE<gt>>]>
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
B<-d --dir /path/to/profiles>
|
||||
|
||||
The path to where the AppArmor security profiles are stored
|
||||
|
||||
B<-f --file /path/to/logfile>
|
||||
|
||||
The path to the location of the logfile that contains AppArmor
|
||||
security events.
|
||||
|
||||
B< -m --logmark "mark">
|
||||
|
||||
logprof will ignore all events in the system log before the
|
||||
specified mark is seen. If the mark contains spaces, it must
|
||||
be surrounded with quotes to work correctly.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<logprof> is an interactive tool used to review AppArmor's syslog
|
||||
complain mode output and generate new entries for AppArmor security
|
||||
profiles.
|
||||
|
||||
Running logprof will scan the log file and if there are new AppArmor
|
||||
events that are not covered by the existing profile set, the user will
|
||||
be prompted with suggested modifications to augment the profile.
|
||||
|
||||
When logprof exits profile changes are saved to disk. If AppArmor is
|
||||
running, the updated profiles are reloaded and if any processes that
|
||||
generated AppArmor events are still running in the null-complain-profile,
|
||||
those processes are set to run under their proper profiles.
|
||||
|
||||
=head2 Responding to AppArmor Events
|
||||
|
||||
B<logprof> will generate a list of "suggested profile changes" that
|
||||
the user can choose from, or they can create their own, to modifiy the
|
||||
permission set of the profile so that the generated access violation
|
||||
will not re-occur.
|
||||
|
||||
The user is then presented with info about the access including profile,
|
||||
path, old mode if there was a previous entry in the profile for this path,
|
||||
new mode, the suggestion list, and given these options:
|
||||
|
||||
(A)llow, (D)eny, (N)ew, (G)lob last piece, (Q)uit
|
||||
|
||||
If the AppArmor profile was in complain mode when the event was generated,
|
||||
the default for this option is (A)llow, otherwise, it's (D)eny.
|
||||
|
||||
The suggestion list is presented as a numbered list with includes
|
||||
at the top, the literal path in the middle, and the suggested globs
|
||||
at the bottom. If any globs are being suggested, the shortest glob
|
||||
is the selected option, otherwise, the literal path is selected.
|
||||
Picking includes from the list must be done manually.
|
||||
|
||||
Hitting a numbered key will change the selected option to the
|
||||
corresponding numbered entry in the list.
|
||||
|
||||
If the user selects (N)ew, they'll be prompted to enter their own globbed
|
||||
entry to match the path. If the user-entered glob does not match the
|
||||
path for this event, they'll be informed and have the option to fix it.
|
||||
|
||||
If the user selects (G)lob last piece then, taking the currently selected
|
||||
option, logprof will remove the last path element and replace it with /*.
|
||||
|
||||
If the last path element already was /*, logprof will go up a directory
|
||||
level and replace it with /**.
|
||||
|
||||
This new globbed entry is then added to the suggestion list and marked
|
||||
as the selected option.
|
||||
|
||||
So /usr/share/themes/foo/bar/baz.gif can be turned into
|
||||
/usr/share/themes/** by hitting "g" three times.
|
||||
|
||||
If the user selects (A)llow, logprof will take the current selection
|
||||
and add it to the profile, deleting other entries in the profile that
|
||||
are matched by the new entry.
|
||||
|
||||
Adding r access to /usr/share/themes/** would delete an entry for r
|
||||
access to /usr/share/themes/foo/*.gif if it exists in the profile.
|
||||
|
||||
If (Q)uit is selected at this point, logprof will ignore all new pending
|
||||
capability and path accesses.
|
||||
|
||||
After all of the path accesses have been handled, logrof will write all
|
||||
updated profiles to the disk and reload them if AppArmor is running.
|
||||
|
||||
=head2 New Process (Execution) Events
|
||||
|
||||
If there are unhandled x accesses generated by the forking of a
|
||||
new process, logprof will display the parent profile and the target
|
||||
program that's being executed and prompt the user to select and execute
|
||||
modifier. These modifiers will allow a choice for the target to: have it's
|
||||
own profile (px), inherit the parent's profile (ix), run unconstrained
|
||||
(ux), or deny access for the target.
|
||||
|
||||
If there is a corresponding entry for the target in the qualifiers
|
||||
section of /etc/logprof.conf, the presented list will contain only the
|
||||
allowed modes.
|
||||
|
||||
The default option for this question is selected using this logic--
|
||||
|
||||
# if px mode is allowed and profile exists for the target
|
||||
# px is default.
|
||||
# else if ix mode is allowed
|
||||
# ix is default
|
||||
# else
|
||||
# deny is default
|
||||
|
||||
logprof will never suggest "ux" as the default.
|
||||
|
||||
=head2 ChangeHat Events
|
||||
|
||||
If unknown changehat events are found, the user is prompted to add a new
|
||||
hat, if the events should go into the default hat for this profile based
|
||||
on the corresponding entry in the defaulthat section of logprof.conf,
|
||||
or if the following events that run under that hat should be denied
|
||||
altogether.
|
||||
|
||||
=head2 Capability Events
|
||||
|
||||
If there are capability accesses, the user is shown each capability
|
||||
access and asked if the capability should be allowed, denied, or if the
|
||||
user wants to quit.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None. Please report any you find to bugzilla at
|
||||
L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
klogd(8), auditd(8), apparmor(7), apparmor.d(5), change_hat(2),
|
||||
logprof.conf(5), genprof(1), complain(1), enforce(1), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
96
docs/mod_apparmor.pod
Normal file
|
@ -0,0 +1,96 @@
|
|||
# $Id: mod_apparmor.pod 6225 2006-02-04 00:25:12Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
mod_apparmor - fine-grained AppArmor confinement for apache
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
An AppArmor profile applies to an executable program; if a portion of
|
||||
the program needs different access permissions than other portions,
|
||||
the program can "change hats" via change_hat(2) to a different role,
|
||||
also known as a subprofile. The mod_apparmor apache module uses the
|
||||
change_hat(2) mechanism to offer more fine-grained confinement of dynamic
|
||||
elements within apache such as individual php and perl scripts, while
|
||||
still allowing the performance benefits of using mod_php and mod_perl.
|
||||
|
||||
To use mod_apparmor with apache, ensure that mod_apparmor is configured to
|
||||
be loaded into apache, either via yast or manual editing of the httpd(8)
|
||||
configuration files, and restart apache. Make sure that apparmor is also
|
||||
functioning.
|
||||
|
||||
Once mod_apparmor is loaded within apache, all requests to apache will
|
||||
cause mod_apparmor to attempt to change into a hat named by the URI
|
||||
(e.g. /app/some.cgi). If no such hat is found, it will fall back to
|
||||
attempting to use the hat DEFAULT_URI; if that also does not exist,
|
||||
it will fall back to using the global apache profile. Most static web
|
||||
pages can simply make use of the DEFAULT_URI hat.
|
||||
|
||||
However, defining hats for every URI/URL would become tedious, so there
|
||||
are a couple of configuration options that mod_apparmor supports:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<AAHatName>
|
||||
|
||||
AAHatName allows you to specify a hat to be used for a given apache
|
||||
directory or location directive (see the apache documenation for more
|
||||
details). Note that mod_apparmor behavior can become confused if
|
||||
directory and location directives are intermingled; it's preferred to
|
||||
stick to one type of directive. If the hat specified by AAHatName does
|
||||
not exist in the apache profile, then it falls back to the behavior
|
||||
above.
|
||||
|
||||
=item B<AADefaultHatName>
|
||||
|
||||
AADefaultHatName allows you to specify a default hat to be used for
|
||||
vhosts and other apache server directives, so that you can have
|
||||
different defaults for different virtual hosts. This can be overridden
|
||||
by an AAHatName directive. If the AADefaultHatName hat does not exist,
|
||||
it falls back to the behavior described above.
|
||||
|
||||
=back
|
||||
|
||||
Additionally, before any requests come in to apache, mod_apparmor
|
||||
will attempt to change hat into the HANDLING_UNTRUSTED_INPUT hat.
|
||||
mod_apparmor will attempt to use this hat while apache is doing the
|
||||
initial parsing of a given http request, before its given to a specific
|
||||
handler (like mod_php) for processing.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
mod_apparmor() currently only supports apache2, and has only been tested
|
||||
with the prefork MPM configuration -- threaded configurations of apache
|
||||
may not work correctly.
|
||||
|
||||
There are likely other bugs lurking about; if you find any, please report
|
||||
them to bugzilla at L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), subdomain.conf(5), apparmor_parser(8), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
BIN
docs/papers/discex00.pdf
Normal file
BIN
docs/papers/discex3_autonomix_defcon.pdf
Normal file
BIN
docs/papers/formatguard-sec01.pdf
Normal file
BIN
docs/papers/lsm-sec02.pdf
Normal file
BIN
docs/papers/raceguard-sec01.pdf
Normal file
BIN
docs/papers/subdomain-lisa00.pdf
Normal file
BIN
docs/papers/usenixsc98.pdf
Normal file
93
docs/raceguard.pod
Normal file
|
@ -0,0 +1,93 @@
|
|||
# $Id: raceguard.pod 5820 2005-11-30 19:51:33Z sarnold $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
RaceGuard - File system race protection
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
It is a common programming idiom to perform an lstat(2) or stat(2) on a
|
||||
potential temporary filename and create the file with open(2) using
|
||||
O_CREAT as an argument. When this is used without the O_EXCL flag, a
|
||||
symbolic or hard link could be sneaked into the filename selected before
|
||||
the lstat(2) or stat(2) returned and before open(2) is called, causing
|
||||
the program to follow a link it did not anticipate. This behavior is
|
||||
unfortunately codified in the mktemp(3) function.
|
||||
|
||||
This filesystem race, in conjunction with setuid or setgid applications,
|
||||
or daemons running with different privilege levels, can be used to read
|
||||
or write files the attacker wouldn't normally be able to access.
|
||||
|
||||
RaceGuard works by preparing a per-process cache of recent
|
||||
stat(2) filenames where stat(2) returns a notice that the file does not
|
||||
exist; if a process then tries to open(2) O_CREAT without O_EXCL this
|
||||
filename, RaceGuard will first check if a file with that name exists. If
|
||||
it does, then some external process has likely raced this process, and
|
||||
RaceGuard will either fail the open(2) or it will kill the process,
|
||||
depending upon a sysctl.
|
||||
|
||||
To simply fail the open(2) calls:
|
||||
# echo 0 > /proc/sys/kernel/raceguard_kill
|
||||
|
||||
To cause the raced process to be killed:
|
||||
# echo 1 > /proc/sys/kernel/raceguard_kill
|
||||
|
||||
This value is also visible through the sysctl(8) mechanism.
|
||||
|
||||
To see RaceGuard in action, start two terminal shells.
|
||||
In shell one do:
|
||||
$ rm source target
|
||||
$ ln -s target source
|
||||
|
||||
In shell two, do:
|
||||
$ touch sou<TAB>
|
||||
|
||||
(We are using the shell's tab-completion for 'source', to cause a
|
||||
stat(2)). When touch(1) runs, it will be killed by RaceGuard, and a
|
||||
message similar to the following will be sent to the system logs:
|
||||
|
||||
Feb 7 18:26:07 lizaveta kernel: Immunix: RaceGuard: Killed bash (pid 30185) when trying to access /home/steve/source!
|
||||
|
||||
|
||||
=cut
|
||||
=head1 Fixing RaceGuard breakage
|
||||
|
||||
Large make(1) systems occasionally encounter problems when run under
|
||||
RaceGuard. Behavior is random, because RaceGuard is actually correctly
|
||||
detecting unknown race vulnerabilities in the make file. Re-starting the
|
||||
build will occasionally mask the problem, as will reducing parallelism
|
||||
to 1. If problems persist, you will need to install a custom kernel or
|
||||
fix the make file to no longer have this concurrency fault. In future
|
||||
versions of Immunix, we expect RaceGuard to be a removable kernel module
|
||||
(see L<http://lsm.immunix.org/>).
|
||||
=pod
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
access(2), lstat(2), stat(2), open(2), fork(2), exec(2), sysctl(8),
|
||||
immunix(7)
|
||||
|
||||
=cut
|
103
docs/subdomain.conf.pod
Normal file
|
@ -0,0 +1,103 @@
|
|||
# $Id: subdomain.conf.pod 6203 2006-02-02 22:03:41Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
=head1 NAME
|
||||
|
||||
/etc/apparmor/subdomain.conf - configuration file for fine-tuning the
|
||||
behavior of the AppArmor security tool.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The AppArmor security tool can be configured to have
|
||||
certain default behaviors based on configuration options set
|
||||
in subdomain.conf. There are two variables that can be set in
|
||||
subdomain.conf: B<SUBDOMAIN_PATH>, and B<SUBDOMAIN_MODULE_PANIC>.
|
||||
|
||||
=begin comment
|
||||
|
||||
FIXME keep quiet about OWLSM support for now.
|
||||
|
||||
=head2 SUBDOMAIN_ENABLE_OWLSM
|
||||
|
||||
This veriable is a yes/no toggle and is by default set to I<no>.
|
||||
|
||||
This variable determines whether the AppArmor initscript will enable
|
||||
or disable the OWLsm security extension to AppArmor when the AppArmor
|
||||
security tool is started. When enabled the OWLsm feature prevents programs
|
||||
from following symlinks in temporary directories that are not owned by
|
||||
the program's UID, and prevents processes from creating hardlinks to
|
||||
files not owned by their UID.
|
||||
|
||||
=end comment
|
||||
|
||||
=head2 SUBDOMAIN_PATH
|
||||
|
||||
This variable accepts a string (path), and is by default set to
|
||||
'/etc/apparmor.d/' This variable defines where the AppArmor security
|
||||
tool looks for its policy definitions (a.k.a. AppArmor profiles).
|
||||
|
||||
=head2 SUBDOMAIN_MODULE_PANIC
|
||||
|
||||
This variable accepts a string that is one of four values: I<warn>,
|
||||
I<build>, I<panic>, or I<build-panic>, and is set by default to I<warn>.
|
||||
|
||||
This setting controls the behavior of the AppArmor initscript if it
|
||||
cannot successfully load the AppArmor kernel module on startup. The four
|
||||
possible settings are:
|
||||
|
||||
=over 4
|
||||
|
||||
=item I<warn>
|
||||
|
||||
Log a failure message (the default behavior).
|
||||
|
||||
=item I<build>
|
||||
|
||||
Attempt to build the AppArmor module against the currently running
|
||||
kernel. If the compilation is successful, the module will be loaded and
|
||||
AppArmor started; if the compilation fails, a failure message is logged.
|
||||
|
||||
=item I<panic>
|
||||
|
||||
Log a failure message and drop to runlevel 1 (single user).
|
||||
|
||||
=item I<build-panic>
|
||||
|
||||
Attempt to build the module against the running kernel (like I<build>)
|
||||
and if the compilation fails, drop to runlevel 1 (single user).
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Setting the initscript to recompile the module will fail on SUSE, as the
|
||||
module source is no longer installed by default. However, the module has
|
||||
been included with the SUSE kernel, so no rebuilding should be necessary.
|
||||
|
||||
If you find any additional bugs, please report them to
|
||||
bugzilla at L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor_parser(8), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
BIN
docs/theend.fm
Normal file
BIN
docs/ug_apparmor.fm
Normal file
BIN
docs/ug_apparmor.pdf
Normal file
59
docs/unconfined.pod
Normal file
|
@ -0,0 +1,59 @@
|
|||
# $Id: unconfined.pod 6203 2006-02-02 22:03:41Z steve $
|
||||
# This publication is intellectual property of Novell Inc. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither SUSE LINUX GmbH, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. SUSE LINUX GmbH
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
unconfined - output a list of processes with tcp or udp ports that do
|
||||
not have AppArmor profiles loaded
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<unconfined>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<unconfined> will use netstat(8) to determine which processes have open
|
||||
network sockets and do not have AppArmor profiles loaded into the kernel.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
B<unconfined> must be run as root to retrieve the process executable
|
||||
link from the F</proc> filesystem. This program is susceptible to race
|
||||
conditions of several flavours: an unlinked executable will be mishandled;
|
||||
an executable started before a AppArmor profile is loaded will not
|
||||
appear in the output, despite running without confinement; a process that dies
|
||||
between the netstat(8) and further checks will be mishandled. This
|
||||
program only lists processes using TCP and UDP. In short, this
|
||||
program is unsuitable for forensics use and is provided only as an aid
|
||||
to profiling all network-accessible processes in the lab.
|
||||
|
||||
If you find any bugs, please report them to bugzilla at
|
||||
L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
netstat(8), apparmor(7), apparmor.d(5), change_hat(2), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
2
management/yastui/.cvsignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
Make.rules
|
||||
yast2-subdomain*.tar.gz
|
504
management/yastui/COPYING.LGPL
Normal file
|
@ -0,0 +1,504 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
65
management/yastui/Makefile
Normal file
|
@ -0,0 +1,65 @@
|
|||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# Makefile for YaST2 Plugins for SD
|
||||
#
|
||||
NAME=yast2-apparmor
|
||||
all:
|
||||
COMMONDIR=../../common/
|
||||
|
||||
include Make.rules
|
||||
|
||||
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
|
||||
ifeq ($(COMMONDIR_EXISTS), true)
|
||||
Make.rules: $(COMMONDIR)/Make.rules src/locale/Make.rules src/po/Make.rules
|
||||
ln -f $(COMMONDIR)/Make.rules .
|
||||
|
||||
src/po/Make.rules: $(COMMONDIR)/Make-po.rules
|
||||
make -C src/po Make.rules
|
||||
|
||||
src/locale/Make.rules: $(COMMONDIR)/Make-po.rules
|
||||
make -C src/locale Make.rules
|
||||
|
||||
endif
|
||||
|
||||
SUBDIRS = clients include scrconf desktop agents perl icons bin
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
mkdir -p ${DESTDIR}/usr/share/YaST2/clients
|
||||
mkdir -p ${DESTDIR}/usr/share/YaST2/include/subdomain
|
||||
mkdir -p ${DESTDIR}/usr/share/YaST2/scrconf
|
||||
mkdir -p ${DESTDIR}/usr/share/applications/YaST2
|
||||
mkdir -p ${DESTDIR}/usr/share/applications/YaST2/groups
|
||||
mkdir -p ${DESTDIR}/usr/lib/YaST2/servers_non_y2
|
||||
mkdir -p ${DESTDIR}/usr/lib/perl5/vendor_perl/Immunix
|
||||
mkdir -p ${DESTDIR}/usr/share/YaST2/theme/SuSELinux/icons/48x48/apps/apparmor
|
||||
mkdir -p ${DESTDIR}/usr/share/YaST2/theme/SuSELinux/icons/32x32/apps/apparmor
|
||||
mkdir -p ${DESTDIR}/usr/share/YaST2/theme/SuSELinux/icons/22x22/apps/apparmor
|
||||
mkdir -p ${DESTDIR}/usr/bin
|
||||
mkdir -p ${DESTDIR}/etc/apparmor
|
||||
cp -a src/clients/* ${DESTDIR}/usr/share/YaST2/clients/
|
||||
cp -a src/include/* ${DESTDIR}/usr/share/YaST2/include/
|
||||
cp -a src/scrconf/* ${DESTDIR}/usr/share/YaST2/scrconf/
|
||||
cp -a src/desktop/* ${DESTDIR}/usr/share/applications/YaST2/
|
||||
cp -a src/desktop/groups/* ${DESTDIR}/usr/share/applications/YaST2/groups/
|
||||
cp -a src/perl/* ${DESTDIR}/usr/lib/perl5/vendor_perl/Immunix
|
||||
cp -a src/icons/48x48/* ${DESTDIR}/usr/share/YaST2/theme/SuSELinux/icons/48x48/apps/apparmor
|
||||
cp -a src/icons/32x32/* ${DESTDIR}/usr/share/YaST2/theme/SuSELinux/icons/32x32/apps/apparmor
|
||||
cp -a src/icons/22x22/* ${DESTDIR}/usr/share/YaST2/theme/SuSELinux/icons/22x22/apps/apparmor
|
||||
cp -a src/bin/* ${DESTDIR}/usr/bin
|
||||
cp -a src/apparmor/* ${DESTDIR}/etc/apparmor
|
||||
install -m 755 src/agents/* ${DESTDIR}/usr/lib/YaST2/servers_non_y2/
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(TARBALL) ${NAME}-${VERSION}-*.tar.gz
|
251
management/yastui/src/agents/ag_genprof
Executable file
|
@ -0,0 +1,251 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
use Locale::gettext;
|
||||
use POSIX;
|
||||
|
||||
use Immunix::SubDomain;
|
||||
|
||||
# initialize the local poo
|
||||
setlocale(LC_MESSAGES, "");
|
||||
textdomain("apparmor-utils");
|
||||
|
||||
setup_yast();
|
||||
|
||||
$running_under_genprof = 1;
|
||||
|
||||
# options variables
|
||||
my $help = '';
|
||||
|
||||
GetOptions(
|
||||
'file|f=s' => \$filename,
|
||||
'dir|d=s' => \$profiledir,
|
||||
'help|h' => \$help,
|
||||
);
|
||||
|
||||
# tell 'em how to use it...
|
||||
&usage && exit if $help;
|
||||
|
||||
my $sd_mountpoint = check_for_subdomain();
|
||||
unless($sd_mountpoint) {
|
||||
fatal_error(gettext("SubDomain does not appear to be started. Please enable SubDomain and try again."));
|
||||
}
|
||||
|
||||
# let's convert it to full path...
|
||||
$profiledir = get_full_path($profiledir);
|
||||
|
||||
unless(-d $profiledir) {
|
||||
fatal_error "Can't find subdomain profiles in $profiledir.";
|
||||
}
|
||||
|
||||
# what are we profiling?
|
||||
my $profiling;
|
||||
my $fqdbin;
|
||||
|
||||
do {
|
||||
|
||||
my $f = {
|
||||
description =>
|
||||
|
||||
"This wizard will help you create a new AppArmor security
|
||||
profile for an application, or you can use it to enhance
|
||||
an existing profile by allowing AppArmor to learn new
|
||||
application behavior.
|
||||
|
||||
Please enter the application name for which you would like
|
||||
to create a profile, or selecte Browse to find the
|
||||
application on your system.",
|
||||
file_label => "&Application to Profile",
|
||||
okay_label => "&Create",
|
||||
cancel_label => "&Abort",
|
||||
browse_desc => "Select Program to Profile",
|
||||
};
|
||||
|
||||
my $profiling = UI_GetFile( $f );
|
||||
if(not defined $profiling) {
|
||||
|
||||
# they hit cancel
|
||||
shutdown_yast();
|
||||
exit 0;
|
||||
|
||||
} elsif($profiling) {
|
||||
|
||||
# they selected something, see if it exists or we can find it in $PATH
|
||||
$fqdbin = "";
|
||||
if(-f $profiling) {
|
||||
$fqdbin = get_full_path($profiling);
|
||||
chomp($fqdbin);
|
||||
|
||||
unless(-x $fqdbin) {
|
||||
UI_Important("The specified file is not executable.
|
||||
|
||||
Please enter an application name to
|
||||
continue generating a profile or press
|
||||
Abort to cancel this wizard.");
|
||||
}
|
||||
} elsif(-d $profiling) {
|
||||
UI_Important("The specified pathname is a directory.
|
||||
|
||||
Please enter an application name to
|
||||
continue generating a profile or press
|
||||
Abort to cancel this wizard.");
|
||||
} else {
|
||||
if($profiling !~ /\//) {
|
||||
my $which = which($profiling);
|
||||
if($which) {
|
||||
$fqdbin = get_full_path($which);
|
||||
}
|
||||
}
|
||||
|
||||
unless(-f $fqdbin) {
|
||||
UI_Important("The specified file does not exist.
|
||||
|
||||
Please enter an application name to
|
||||
continue generating a profile or press
|
||||
Abort to cancel this wizard.");
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
# they hit okay without entering anything
|
||||
UI_Important(gettext("You have not entered or selected an
|
||||
application to profile.
|
||||
|
||||
Please enter an application name to
|
||||
continue generating a profile or press
|
||||
Abort to cancel this wizard."));
|
||||
}
|
||||
|
||||
} until($fqdbin && -x $fqdbin);
|
||||
|
||||
# read the settings in /etc/logprof.conf
|
||||
readconfig();
|
||||
|
||||
# make sure that the app they're requesting to profile is not marked as
|
||||
# not allowed to have it's own profile
|
||||
if($qualifiers{$fqdbin}) {
|
||||
unless($qualifiers{$fqdbin} =~ /p/) {
|
||||
fatal_error(sprintf(gettext(
|
||||
"\%s is currently marked as a program that should not have
|
||||
it's own profile. Usually, programs are marked this way
|
||||
if creating a profile for them is likely to break the
|
||||
rest of the system. If you know what you're doing and
|
||||
are certain you want to create a profile for this program,
|
||||
edit the corresponding entry in the [qualifiers] section
|
||||
in /etc/apparmor/logprof.conf."
|
||||
), $fqdbin));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# load all the include files
|
||||
loadincludes();
|
||||
|
||||
my $profilefilename = getprofilefilename($fqdbin);
|
||||
if(-e $profilefilename) {
|
||||
$helpers{$fqdbin} = getprofileflags($profilefilename) || "enforce";
|
||||
} else {
|
||||
autodep($fqdbin);
|
||||
$helpers{$fqdbin} = "enforce";
|
||||
}
|
||||
|
||||
if($helpers{$fqdbin} eq "enforce") {
|
||||
complain($fqdbin);
|
||||
reload($fqdbin);
|
||||
}
|
||||
|
||||
my $done_profiling = 0;
|
||||
my $syslog = 1;
|
||||
$syslog = 0 if ( -e "/var/log/audit/audit.log" );
|
||||
|
||||
while(not $done_profiling) {
|
||||
|
||||
my $logmark = "";
|
||||
if ( $syslog ) {
|
||||
$logmark = `date | md5sum`;
|
||||
chomp $logmark;
|
||||
$logmark = $1 if $logmark =~ /^([0-9a-f]+)/;
|
||||
system("logger -p kern.warn 'GenProf: $logmark'");
|
||||
} else {
|
||||
$logmark = last_audit_entry_time();
|
||||
}
|
||||
|
||||
my $q = { };
|
||||
$q->{headers} = [ gettext("Profiling"), $fqdbin ];
|
||||
$q->{explanation} = "Please start the application to be profiled in
|
||||
another window and exercise its functionality now.
|
||||
|
||||
Once completed, select the 'Scan' option below in
|
||||
order to scan the system logs for AppArmor events.
|
||||
|
||||
For each AppArmor event, you will be given the
|
||||
opportunity to choose whether the access should be
|
||||
allowed or denied.";
|
||||
$q->{functions} = [ "CMD_SCAN", "CMD_FINISHED" ];
|
||||
$q->{default} = "CMD_SCAN";
|
||||
my ($ans, $arg) = UI_PromptUser($q);
|
||||
|
||||
if($ans eq "CMD_SCAN") {
|
||||
|
||||
my $lp_ret = do_logprof_pass($logmark);
|
||||
|
||||
$done_profiling = 1 if $lp_ret eq "FINISHED";
|
||||
|
||||
} else {
|
||||
|
||||
# make them confirm the exit command
|
||||
my $ans = UI_YesNo(gettext("Are you sure you want to exit?"), "n");
|
||||
if($ans eq "y") {
|
||||
$done_profiling = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for my $p (sort keys %helpers) {
|
||||
if($helpers{$p} eq "enforce") {
|
||||
enforce($p);
|
||||
reload($p);
|
||||
}
|
||||
}
|
||||
|
||||
UI_Info(gettext("Reloaded SubDomain profiles in enforce mode."));
|
||||
UI_Info(sprintf(gettext('Finished generating profile for %s.'), $fqdbin));
|
||||
|
||||
shutdown_yast();
|
||||
|
||||
exit 0;
|
||||
|
||||
sub usage {
|
||||
UI_Info("usage: $0 [ -d /path/to/profiles ] [ -f /path/to/logfile ] [ program to profile ]");
|
||||
exit 0;
|
||||
}
|
||||
|
||||
sub last_audit_entry_time {
|
||||
|
||||
local $_ = `tail -1 /var/log/audit/audit.log`;
|
||||
my $logmark;
|
||||
if ( /^.*msg\=audit\((\d+\.\d+\:\d+).*\).*$/ ) {
|
||||
$logmark = $1;
|
||||
} else {
|
||||
$logmark = "";
|
||||
}
|
||||
return $logmark;
|
||||
}
|
||||
|
404
management/yastui/src/agents/ag_logparse
Executable file
|
@ -0,0 +1,404 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
################################################################################
|
||||
# ag_logparse
|
||||
#
|
||||
# - Generates report of SubDomain events
|
||||
#
|
||||
# Requires:
|
||||
# - /usr/lib/immunix/SubDomain/perl/Immunix::Reports.pm
|
||||
# - /usr/lib/immunix/SubDomain/perl/Events.pm
|
||||
#
|
||||
# Input (Optional):
|
||||
# -Start Date|End Date (Month, Day, Year, Time)
|
||||
# -Program Name
|
||||
# -Profile Name
|
||||
# -PID
|
||||
# -Severity Level
|
||||
# -Denied Resources
|
||||
# -Mode
|
||||
# -SDMode
|
||||
#
|
||||
################################################################################
|
||||
my $Version='1.03';
|
||||
|
||||
use strict;
|
||||
use Immunix::Reports;
|
||||
use Immunix::Ycp;
|
||||
use POSIX;
|
||||
use Locale::gettext;
|
||||
|
||||
setlocale(LC_MESSAGES, "");
|
||||
textdomain("apparmor-utils");
|
||||
|
||||
use constant DEBUGGING => 0;
|
||||
|
||||
my $numEvents = 1000;
|
||||
|
||||
# Should be deprecated
|
||||
sub saveQuery {
|
||||
|
||||
my $query = shift;
|
||||
my $qLog = '/var/log/apparmor/reports/reporting-query.tmp';
|
||||
|
||||
if ( open(QLOG, ">$qLog") ) {
|
||||
|
||||
print QLOG "$query";
|
||||
|
||||
close QLOG;
|
||||
|
||||
} else {
|
||||
my $error = gettext("Unable to open") . " $qLog " . gettext("Couldn't save query.");
|
||||
Immunix::Ycp::y2error($error);
|
||||
}
|
||||
}
|
||||
|
||||
sub getSavedQuery {
|
||||
|
||||
my $page = shift;
|
||||
my $query = undef;
|
||||
|
||||
my $qLog = '/var/log/apparmor/reports/reporting-query.tmp';
|
||||
|
||||
if ( open(QLOG, "<$qLog") ) {
|
||||
|
||||
$query = <QLOG>;
|
||||
chomp($query);
|
||||
|
||||
close QLOG;
|
||||
|
||||
} else {
|
||||
my $error = gettext("Unable to open") . " $qLog " . gettext("Couldn't retrieve query.");
|
||||
Immunix::Ycp::y2error("Unable to open $qLog. Couldn't retrieve query.");
|
||||
}
|
||||
|
||||
# rewrite query for current page
|
||||
my $limStart = (( $page * $numEvents ) - $numEvents);
|
||||
|
||||
my ($q1) = (split(/LIMIT/, $query))[0];
|
||||
my $q2 = " LIMIT $limStart,$numEvents";
|
||||
|
||||
$query = $q1 . $q2;
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
sub getReportName {
|
||||
|
||||
my $dir = shift;
|
||||
my @dirList = ();
|
||||
|
||||
my $newName = undef;
|
||||
my $plainName = "Security.Incident.Report";
|
||||
|
||||
# Append date info to help id reports
|
||||
my ($sec,$min,$hour,$mday,$month,$year,@junk) = localtime;
|
||||
|
||||
$year += 1900;
|
||||
$month += 1;
|
||||
|
||||
$month = sprintf("%02d", $month);
|
||||
$mday = sprintf("%02d", $mday);
|
||||
$hour = sprintf("%02d", $hour);
|
||||
$min = sprintf("%02d", $min);
|
||||
$sec = sprintf("%02d", $sec);
|
||||
$mday = sprintf("%02d", $mday);
|
||||
|
||||
my $suffix = "-$year-$month-$mday\_$hour.$min.$sec";
|
||||
$plainName = $plainName . $suffix;
|
||||
|
||||
if (opendir (DIR, $dir)) {
|
||||
@dirList = grep(/\"$plainName\"/, readdir(DIR) );
|
||||
close DIR;
|
||||
}
|
||||
|
||||
my $numReps = scalar(@dirList) + 1;
|
||||
$numReps = sprintf("%03d", $numReps);
|
||||
|
||||
$newName = "$dir/$plainName.$numReps";
|
||||
|
||||
return $newName;
|
||||
}
|
||||
|
||||
|
||||
sub getHeader {
|
||||
|
||||
my ($args,$filts) = @_;
|
||||
|
||||
my $date = localtime;
|
||||
my $start = "Jan 1, 2005";
|
||||
my $header = undef;
|
||||
|
||||
my $count = 0;
|
||||
|
||||
if ( $filts ) {
|
||||
# We don't want startdate/enddate to be listed as filters
|
||||
$count = keys(%$filts);
|
||||
if ($filts->{'startdate'}) {
|
||||
$filts->{'startdate'} = localtime($filts->{'startdate'});
|
||||
$start = $filts->{'startdate'};
|
||||
$count--;
|
||||
}
|
||||
if ($filts->{'enddate'}) {
|
||||
$filts->{'enddate'} = localtime($filts->{'enddate'});
|
||||
$count--;
|
||||
}
|
||||
}
|
||||
|
||||
# Write SIR Header in csv format
|
||||
$header->{'csv'} = gettext("# Security Incident Report - Generated by AppArmor\n");
|
||||
$header->{'csv'} .= sprintf(gettext("# Period: %s - %s\n"), $start, $date);
|
||||
|
||||
|
||||
if ( $count > 0 ) {
|
||||
$header->{'csv'} .= gettext("# The following filters were used for report generation:\n");
|
||||
for (sort keys(%$filts)) {
|
||||
unless ( $filts->{'startdate'} || $filts->{'enddate'} ) {
|
||||
$header->{'csv'} .= sprintf(gettext("# Filter: %s, Value: %s\n\n"), $_, $filts->{$_});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$header->{'csv'} .= gettext("# No filters were used for report generation:\n\n\n");
|
||||
}
|
||||
|
||||
# Write SIR Header in html format
|
||||
$header->{'html'} = gettext("<h3>Security Incident Report - Generated by AppArmor</h3>\n");
|
||||
$header->{'html'} .= sprintf(gettext("<h4>Period: %s - %s</h4>\n"), $start, $date);
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
sub exportReports {
|
||||
|
||||
my ($args,$db,$filts) = @_;
|
||||
|
||||
# Export results to file if requested
|
||||
if ( $args->{'exporttext'} || $args->{'exporthtml'} ) {
|
||||
|
||||
my $expLog = undef;
|
||||
my $rawLog = undef;
|
||||
my $expDir = '/var/log/apparmor/reports-exported/';
|
||||
|
||||
if ( $args->{'exportPath'} && -e $args->{'exportPath'} ) {
|
||||
$expDir = $args->{'exportPath'};
|
||||
}
|
||||
|
||||
my $repName = getReportName($expDir);
|
||||
my $header = getHeader($args,$filts);
|
||||
|
||||
#$rawLog = $expDir . $repName;
|
||||
|
||||
if ( $args->{'exporttext'} && $args->{'exporttext'} eq '1') {
|
||||
$expLog = "$repName.csv";
|
||||
Immunix::Reports::exportLog($expLog,$db,$header->{'csv'});
|
||||
}
|
||||
|
||||
if ( $args->{'exporthtml'} && $args->{'exporthtml'} eq '1') {
|
||||
$expLog = "$repName.html";
|
||||
Immunix::Reports::exportLog($expLog,$db,$header->{'html'});
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Main
|
||||
################################################################################
|
||||
|
||||
while ( <STDIN> ) {
|
||||
|
||||
my ($command, $path, $args) = Immunix::Ycp::ParseCommand ($_);
|
||||
|
||||
my $db = undef;
|
||||
my $error = undef;
|
||||
my $page = 1;
|
||||
my $numEvents = '1000'; # Number of event records to return
|
||||
|
||||
if ( $command && $path && $args ) {
|
||||
|
||||
# yast slows down horribly when passing large number of records
|
||||
if ( $args->{'numEvents'} && $args->{'numEvents'} > 0 && $args->{'numEvents'} < 10001 ) {
|
||||
$numEvents = $args->{'numEvents'};
|
||||
}
|
||||
|
||||
if ($args->{'starttime'}) {
|
||||
my ($hrs,$mins) = split(/\:/, $args->{'starttime'});
|
||||
$hrs = sprintf("%02d", $hrs);
|
||||
$mins = sprintf("%02d", $mins);
|
||||
$args->{'starttime'} = "$hrs:$mins";
|
||||
}
|
||||
if ($args->{'endtime'}) {
|
||||
my ($hrs,$mins) = split(/\:/, $args->{'endtime'});
|
||||
$hrs = sprintf("%02d", $hrs);
|
||||
$mins = sprintf("%02d", $mins);
|
||||
$args->{'endtime'} = "$hrs:$mins";
|
||||
}
|
||||
|
||||
if ( $args->{'startmonth'} && $args->{'startday'} ) {
|
||||
$args->{'startdate'} = "$args->{'startmonth'} $args->{'startday'} $args->{'starttime'} $args->{'startyear'}";
|
||||
}
|
||||
|
||||
if ( $args->{'endmonth'} && $args->{'endday'} ) {
|
||||
$args->{'enddate'} = "$args->{'endmonth'} $args->{'endday'} $args->{'endtime'} $args->{'endyear'}";
|
||||
}
|
||||
|
||||
my $archRep = 0;
|
||||
my $onDemand = 0;
|
||||
my $turnPage = 0;
|
||||
|
||||
if ( $args->{'turnPage'} && ($args->{'turnPage'} == 1) ) {
|
||||
$turnPage = $args->{'turnPage'};
|
||||
}
|
||||
|
||||
if ( $args->{'type'} ) {
|
||||
if ( $args->{'type'} eq "onDemand" ) {
|
||||
$onDemand = 1;
|
||||
$args->{'logFile'} = '/var/log/apparmor/reports/events.rpt';
|
||||
} elsif ( $args->{'type'} eq "archRep" ) {
|
||||
$archRep = 1;
|
||||
unless ($args->{'logFile'}) {
|
||||
$args->{'logFile'} = '/var/log/apparmor/reports/all-reports.rpt';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Parse sdmode & mode labels
|
||||
if ( $args->{'sdmode'} ) {
|
||||
if ($args->{'sdmode'} eq "All") {
|
||||
$args->{'sdmode'} = "-"; # Translate from GUI
|
||||
} else {
|
||||
$args->{'sdmode'} =~ s/\&//g;
|
||||
$args->{'sdmode'} =~ s/\://g;
|
||||
$args->{'sdmode'} =~ s/\s//g;
|
||||
$args->{'sdmode'} =~ s/AccessType//g;
|
||||
}
|
||||
}
|
||||
if ( $args->{'mode'} ) {
|
||||
if ($args->{'mode'} eq "All") {
|
||||
$args->{'mode'} = "-";
|
||||
} else {
|
||||
$args->{'mode'} =~ s/\&//g;
|
||||
$args->{'mode'} =~ s/Mode\://g;
|
||||
$args->{'mode'} =~ s/\s//g;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $args->{'page'} && $args->{'page'} =~ /\d+/ && $args->{'page'} > 0 ) {
|
||||
$page = $args->{'page'};
|
||||
}
|
||||
|
||||
my $sortKey = 'time';
|
||||
if ( $args->{'sortKey'} ) { $sortKey = $args->{'sortKey'}; }
|
||||
|
||||
# debug
|
||||
########################################
|
||||
#if ($args) {
|
||||
# my $argList = "";
|
||||
# for (sort keys(%$args) ) { $argList .= "$_ is $args->{$_}, "; }
|
||||
# Immunix::Ycp::y2milestone("Today's Available Args: $argList");
|
||||
#}
|
||||
########################################
|
||||
|
||||
if ( $args->{'sort'} && $args->{'sort'} == 1 ) {
|
||||
|
||||
my $filts = Immunix::Reports::setFormFilters($args);
|
||||
$filts = Immunix::Reports::rewriteFilters($filts);
|
||||
my $query = Immunix::Reports::getQuery($filts,$page,$sortKey,$numEvents);
|
||||
$db = Immunix::Reports::getEvents($query);
|
||||
|
||||
} elsif ( $turnPage == 1 ) {
|
||||
|
||||
if ( $args->{'turnArch'} && $args->{'turnArch'} == 1 ) {
|
||||
|
||||
$db = Immunix::Reports::getArchReport($args);
|
||||
$turnPage = 1;
|
||||
|
||||
} else {
|
||||
|
||||
# commented lines below work
|
||||
#my $query = getSavedQuery($page);
|
||||
#$db = Immunix::Reports::getEvents($query);
|
||||
#############################################
|
||||
my $filts = Immunix::Reports::setFormFilters($args);
|
||||
$filts = Immunix::Reports::rewriteFilters($filts);
|
||||
my $query = Immunix::Reports::getQuery($filts,$page,$sortKey,$numEvents);
|
||||
$db = Immunix::Reports::getEvents($query);
|
||||
|
||||
}
|
||||
|
||||
} elsif ( $archRep == 1 ) {
|
||||
|
||||
# Parse Logs (Probably Archived Immunix::Reports)
|
||||
##################################################
|
||||
if ($args->{'single'} && $args->{'single'} eq "1" ) {
|
||||
$error = Immunix::Reports::prepSingleLog($args);
|
||||
$args->{'logFile'} = '/var/log/apparmor/reports/all-reports.rpt';
|
||||
} else {
|
||||
$error = Immunix::Reports::prepArchivedLogs($args);
|
||||
}
|
||||
|
||||
if ( ! $error || ($error && ($error eq '0')) ) {
|
||||
$error = Immunix::Reports::parseLog($args);
|
||||
delete($args->{'logFile'});
|
||||
#$db = Immunix::Reports::getArchReport($args);
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error("ag_logparse - Unable to run archived reports: $error");
|
||||
}
|
||||
|
||||
} elsif ($onDemand == 1) {
|
||||
|
||||
# Parse Events (On-Demand report from events db)
|
||||
##################################################
|
||||
#my $filts = Immunix::Reports::getSirFilters($args);
|
||||
my $filts = Immunix::Reports::setFormFilters($args);
|
||||
$filts = Immunix::Reports::rewriteFilters($filts);
|
||||
my $query = Immunix::Reports::getQuery($filts,$page,$sortKey,$numEvents);
|
||||
$db = Immunix::Reports::getEvents($query);
|
||||
|
||||
exportReports($args,$db,$filts);
|
||||
|
||||
# New - write out query for later use in page-turning
|
||||
#saveQuery($query);
|
||||
|
||||
} elsif ($args->{'getSirFilters'} && $args->{'getSirFilters'} == 1) {
|
||||
|
||||
if ( ref($args) && $args->{'name'} ) {
|
||||
$db = Immunix::Reports::getSirFilters($args);
|
||||
} else {
|
||||
$db = Immunix::Reports::getSirFilters();
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $error || ($error eq "0") ) {
|
||||
Immunix::Ycp::ycpReturn( $db );
|
||||
} elsif ( $error ne "0" ) {
|
||||
Immunix::Ycp::y2error("ag_logparse: $error");
|
||||
Immunix::Ycp::ycpReturn( $error );
|
||||
exit 1;
|
||||
} else {
|
||||
Immunix::Ycp::ycpReturn( $error );
|
||||
}
|
||||
|
||||
} else {
|
||||
#my $error = sprintf( gettext("ag_logparse: Unknown instruction %s or argument: %s"), ycpGetCommand, ycpGetArgType);
|
||||
my $error = "ag_logparse: Missing instruction or argument!";
|
||||
Immunix::Ycp::y2error($error);
|
||||
Immunix::Ycp::ycpReturn($error);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
64
management/yastui/src/agents/ag_logprof
Executable file
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# $Id: ag_logprof 5900 2005-12-08 19:12:56Z steve $
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
use strict;
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
use Locale::gettext;
|
||||
use POSIX;
|
||||
|
||||
use Immunix::SubDomain;
|
||||
|
||||
sub usage {
|
||||
UI_Info("usage: $0 [ -d /path/to/profiles ] [ -f /path/to/logfile ] [ -m \"mark in log to start processing after\"");
|
||||
exit 0;
|
||||
}
|
||||
|
||||
# initialize the local poo
|
||||
setlocale(LC_MESSAGES, "");
|
||||
textdomain("apparmor-utils");
|
||||
|
||||
setup_yast();
|
||||
|
||||
# options variables
|
||||
my $help = '';
|
||||
my $logmark;
|
||||
|
||||
GetOptions(
|
||||
'file|f=s' => \$filename,
|
||||
'dir|d=s' => \$profiledir,
|
||||
'logmark|m=s' => \$logmark,
|
||||
'help|h' => \$help,
|
||||
);
|
||||
|
||||
# tell 'em how to use it...
|
||||
&usage && exit if $help;
|
||||
|
||||
# let's convert it to full path...
|
||||
$profiledir = get_full_path($profiledir);
|
||||
|
||||
unless(-d $profiledir) {
|
||||
fatal_error "Can't find subdomain profiles in $profiledir.";
|
||||
}
|
||||
|
||||
# read the settings in /etc/logprof.conf
|
||||
readconfig();
|
||||
|
||||
# load all the include files
|
||||
loadincludes();
|
||||
|
||||
do_logprof_pass($logmark);
|
||||
|
||||
shutdown_yast();
|
||||
exit 0;
|
314
management/yastui/src/agents/ag_reports_confined
Executable file
|
@ -0,0 +1,314 @@
|
|||
#!/usr/bin/perl
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
use strict;
|
||||
use Immunix::Ycp;
|
||||
use POSIX;
|
||||
use Locale::gettext;
|
||||
|
||||
setlocale(LC_MESSAGES, "");
|
||||
textdomain("apparmor-utils");
|
||||
|
||||
# Routines
|
||||
################################################################################
|
||||
sub debug {
|
||||
|
||||
my $db = shift;
|
||||
|
||||
if ((@$db) > 1) {
|
||||
for ( @$db ) {
|
||||
print "Prog: $_->{'prog'}, Prof: $_->{'prof'}, PID: $_->{'pid'}, ";
|
||||
print "State: $_->{'state'}, Type: $_->{'type'}\n";
|
||||
}
|
||||
print "\n";
|
||||
|
||||
} else {
|
||||
print "$db\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
return 0; # Shouldn't get here
|
||||
}
|
||||
|
||||
sub test_getCfInfo {
|
||||
|
||||
my $cfTest = shift;
|
||||
|
||||
my @cfDb = ();
|
||||
|
||||
my $host = `hostname`;
|
||||
chomp($host);
|
||||
|
||||
my $date = localtime;
|
||||
|
||||
for (@$cfTest) {
|
||||
my $ref = ();
|
||||
my $all = undef;
|
||||
chomp;
|
||||
|
||||
$ref->{'host'} = $host;
|
||||
$ref->{'date'} = $date;
|
||||
|
||||
($ref->{'pid'}, $ref->{'prog'}, $all) = split(/\s+/, $_, 3);
|
||||
$all = /\s*((not)*\s*confined\s*(by)*)/;
|
||||
$ref->{'state'} = $1;
|
||||
$ref->{'state'} =~ s/\s*by//g;
|
||||
$ref->{'state'} =~ s/not\s+/not-/g;
|
||||
($ref->{'prof'}, $ref->{'type'}) = split(/\s+/, $_);
|
||||
|
||||
push (@cfDb, $ref);
|
||||
}
|
||||
|
||||
if ( scalar(@cfDb) < 1 ) {
|
||||
return "Error: parsing all messed up!!\n";
|
||||
}
|
||||
|
||||
return (\@cfDb);
|
||||
}
|
||||
|
||||
|
||||
# Writes out file to allow for multiple pages in YaST form
|
||||
# -For large number of entries in the array
|
||||
sub writePagingFile {
|
||||
|
||||
my $db = shift;
|
||||
|
||||
my $pagingFile = "/var/log/apparmor/reports/events.rpt";
|
||||
|
||||
if ( open(PF, ">$pagingFile") ) {
|
||||
|
||||
my $i = 1;
|
||||
my $page = 1;
|
||||
my $skip = 0;
|
||||
|
||||
print PF "Page $page\n";
|
||||
$page++;
|
||||
|
||||
for (@$db) {
|
||||
|
||||
# Order (for YaST): "host", "date", "prog", "prof", "pid", "state", "type"
|
||||
print PF "$_->{'host'},$_->{'date'},$_->{'prog'},$_->{'prof'},$_->{'pid'},$_->{'state'},$_->{'type'}\n";
|
||||
|
||||
if ( ($i % 100) == 0 && $skip == 0) {
|
||||
print PF "Page $page\n";
|
||||
$page++;
|
||||
$skip = 1;
|
||||
} else {
|
||||
$i++;
|
||||
$skip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
close PF;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("ag_reports_confined: Couldn't open %s for writing."), $pagingFile));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub readMultiAudLog {
|
||||
|
||||
my $args = shift;
|
||||
my @audDb = ();
|
||||
my @rawDb = ();
|
||||
my @repList = ();
|
||||
my $dir = '/var/log/apparmor/reports-archived';
|
||||
my $logFile = undef;
|
||||
my $error = undef;
|
||||
my @errors = undef;
|
||||
|
||||
if ( $args->{'repPath'} ) { $dir = $args->{'repPath'}; }
|
||||
|
||||
# Get list of files in archived report directory
|
||||
if ( opendir (RDIR, $dir) ) {
|
||||
|
||||
@repList = grep(/Applications.Audit/, readdir(RDIR));
|
||||
close RDIR;
|
||||
|
||||
} else {
|
||||
$error = sprintf(gettext("Failure in readMultiAudLog() - couldn't open %s."), $dir);
|
||||
return($error); # debug - exit instead?
|
||||
}
|
||||
|
||||
for (@repList) {
|
||||
|
||||
my $file = $_;
|
||||
|
||||
next if $file =~ /$\.html/;
|
||||
|
||||
# Cycle through each $file in $dir
|
||||
if (open (RPT, "<$dir/$file") ) {
|
||||
push(@rawDb, <RPT>);
|
||||
close RPT;
|
||||
} else {
|
||||
$error = sprintf(gettext("Problem in readMultiAudLog\(\) - couldn't open %s\/%s."), $dir, $file);
|
||||
#$error = "Problem in readMultiAudLog() - couldn't open $dir/$file.";
|
||||
push(@errors, $error);
|
||||
}
|
||||
}
|
||||
|
||||
for (@rawDb) {
|
||||
next if /^#/;
|
||||
chomp;
|
||||
next if (! $_ || $_ eq "");
|
||||
|
||||
my $rec = undef;
|
||||
|
||||
( $rec->{'host'}, $rec->{'date'}, $rec->{'prog'}, $rec->{'prof'}, $rec->{'pid'},
|
||||
$rec->{'state'}, $rec->{'type'} ) = split(/\,/, $_);
|
||||
|
||||
push(@audDb, $rec);
|
||||
}
|
||||
|
||||
|
||||
return (\@audDb);
|
||||
}
|
||||
|
||||
sub readAudLog {
|
||||
|
||||
my $args = shift;
|
||||
my @audDb = ();
|
||||
my $dir = '/var/log/apparmor/reports-archived';
|
||||
my $logFile = undef;
|
||||
my $error = undef;
|
||||
|
||||
if ($args->{'file'}) {
|
||||
$logFile = $args->{'file'};
|
||||
} else {
|
||||
$error = gettext("readAudLog() wasn't passed an input file.");
|
||||
Immunix::Ycp::y2error($error);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if ( open(AUD, "<$dir/$logFile") ) {
|
||||
|
||||
while (<AUD>) {
|
||||
|
||||
next if /^#/;
|
||||
chomp;
|
||||
next unless ($_);
|
||||
|
||||
my $rec = undef;
|
||||
|
||||
( $rec->{'host'}, $rec->{'date'}, $rec->{'prog'}, $rec->{'prof'}, $rec->{'pid'},
|
||||
$rec->{'state'}, $rec->{'type'} ) = split(/\,/, $_);
|
||||
|
||||
push(@audDb, $rec);
|
||||
}
|
||||
|
||||
close AUD;
|
||||
|
||||
} else {
|
||||
$error = sprintf(gettext("readAudLog\(\) couldn't open %s."), $logFile);
|
||||
Immunix::Ycp::y2error($error);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
return (\@audDb);
|
||||
}
|
||||
|
||||
sub getCfInfo {
|
||||
|
||||
my $ref = ();
|
||||
my @cfDb = ();
|
||||
|
||||
my $cfApp = '/usr/sbin/unconfined';
|
||||
|
||||
if ( open (CF, "$cfApp |") ) {
|
||||
|
||||
my $host = `hostname`;
|
||||
chomp($host);
|
||||
|
||||
my $date = localtime;
|
||||
|
||||
while(<CF>) {
|
||||
|
||||
my $ref = ();
|
||||
my $all = undef;
|
||||
my $info = undef;
|
||||
$ref->{'host'} = $host;
|
||||
$ref->{'date'} = $date;
|
||||
chomp;
|
||||
|
||||
($ref->{'pid'}, $ref->{'prog'}, $all) = split(/\s+/, $_, 3);
|
||||
$info = $all;
|
||||
$all = /\s*((not)*\s*confined\s*(by)*)/;
|
||||
$ref->{'state'} = $1;
|
||||
$ref->{'state'} =~ s/\s*by//g;
|
||||
$ref->{'state'} =~ s/not\s+/not-/g;
|
||||
|
||||
if ($ref->{'state'} =~ /not-confined/ ) {
|
||||
$ref->{'prof'} = "-";
|
||||
$ref->{'type'} = "-";
|
||||
} else {
|
||||
($info) = (split(/\'/, $info, 2))[1];
|
||||
($ref->{'prof'}, $ref->{'type'}) = split(/\s+/, $info);
|
||||
$ref->{'type'} =~ s/\(|\)|\'//g;
|
||||
}
|
||||
|
||||
if ( $ref->{'prog'} eq "") { $ref->{'prog'} = "-"; }
|
||||
if ( $ref->{'prof'} eq "") { $ref->{'prof'} = "-"; }
|
||||
if ( $ref->{'pid'} eq "") { $ref->{'pid'} = "-"; }
|
||||
if ( $ref->{'state'} eq "") { $ref->{'state'} = "-"; }
|
||||
if ( $ref->{'type'} eq "") { $ref->{'type'} = "-"; }
|
||||
|
||||
push (@cfDb, $ref);
|
||||
}
|
||||
close CF;
|
||||
|
||||
} else {
|
||||
my $error = sprintf(gettext("Can't run %s. Exiting."), $cfApp);
|
||||
Immunix::Ycp::y2error($error);
|
||||
return $error;
|
||||
}
|
||||
|
||||
return (\@cfDb);
|
||||
}
|
||||
|
||||
# Main
|
||||
################################################################################
|
||||
|
||||
|
||||
while ( <STDIN> ) {
|
||||
|
||||
my ($command, $path, $args) = Immunix::Ycp::ParseCommand ($_);
|
||||
|
||||
if ( $command && $path && $args ) {
|
||||
|
||||
my $db = undef;
|
||||
|
||||
if ($args->{'audArch'} && $args->{'audArch'} == 1) {
|
||||
|
||||
if (! $args->{'single'} || $args->{'single'} != 1 ) {
|
||||
$db = readMultiAudLog($args);
|
||||
} else {
|
||||
$db = readAudLog($args);
|
||||
}
|
||||
|
||||
} else {
|
||||
$db = getCfInfo();
|
||||
}
|
||||
|
||||
writePagingFile($db);
|
||||
Immunix::Ycp::ycpReturn( $db );
|
||||
|
||||
} else {
|
||||
my $error = gettext("ag_reports_confined: Missing instruction or argument!");
|
||||
Immunix::Ycp::y2error($error);
|
||||
Immunix::Ycp::ycpReturn($error);
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
170
management/yastui/src/agents/ag_reports_ess
Executable file
|
@ -0,0 +1,170 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
################################################################################
|
||||
# ag_reports_ess
|
||||
#
|
||||
# - Generates Report of SubDomain Executive Security Summary
|
||||
#
|
||||
# Requires:
|
||||
# - /usr/lib/immunix/SubDomain/perl/Immunix/Events.pm
|
||||
# - /usr/lib/immunix/SubDomain/perl/Immunix/Reports.pm
|
||||
#
|
||||
# Input (Optional):
|
||||
#
|
||||
################################################################################
|
||||
|
||||
use strict;
|
||||
use Immunix::Ycp;
|
||||
use Immunix::Reports;
|
||||
use POSIX;
|
||||
use Locale::gettext;
|
||||
|
||||
setlocale(LC_MESSAGES, "");
|
||||
textdomain("apparmor-utils");
|
||||
|
||||
sub readMultiEssLog {
|
||||
|
||||
my $args = shift;
|
||||
my @essDb = ();
|
||||
my @rawDb = ();
|
||||
my @repList = ();
|
||||
my $dir = '/var/log/apparmor/reports-archived';
|
||||
my $logFile = undef;
|
||||
my $error = undef;
|
||||
my @errors = undef;
|
||||
|
||||
if ( $args->{'repPath'} ) { $dir = $args->{'repPath'}; }
|
||||
|
||||
# Get list of files in archived report directory
|
||||
if ( opendir (RDIR, $dir) ) {
|
||||
|
||||
@repList = grep(/Executive.Security.Summary/, readdir(RDIR));
|
||||
close RDIR;
|
||||
|
||||
} else {
|
||||
$error = gettext("Failure in readMultiEssLog() - couldn't open") . " $dir.";
|
||||
return($error); # debug - exit instead?
|
||||
}
|
||||
|
||||
for (@repList) {
|
||||
|
||||
my $file = $_;
|
||||
|
||||
# Cycle through each $file in $dir
|
||||
if (open (RPT, "<$dir/$file") ) {
|
||||
push(@rawDb, <RPT>);
|
||||
close RPT;
|
||||
} else {
|
||||
$error = gettext("Problem in readMultiEssLog() - couldn't open") . " $dir/$file.";
|
||||
push(@errors, $error);
|
||||
}
|
||||
}
|
||||
|
||||
for (@rawDb) {
|
||||
next if /^#/;
|
||||
chomp;
|
||||
next if (! $_ || $_ eq "");
|
||||
|
||||
my $rec = undef;
|
||||
|
||||
( $rec->{'host'}, $rec->{'startdate'}, $rec->{'enddate'}, $rec->{'sevHi'},
|
||||
$rec->{'sevMean'}, $rec->{'numRejects'},$rec->{'numEvents'} ) = split(/\,/, $_);
|
||||
|
||||
|
||||
push(@essDb, $rec);
|
||||
}
|
||||
|
||||
|
||||
return (\@essDb);
|
||||
|
||||
}
|
||||
|
||||
sub readEssLog {
|
||||
|
||||
my $args = shift;
|
||||
my @essDb = ();
|
||||
my $dir = '/var/log/apparmor/reports-archived';
|
||||
my $logFile = undef;
|
||||
my $error = undef;
|
||||
|
||||
if ($args->{'file'}) {
|
||||
$logFile = $args->{'file'};
|
||||
} else {
|
||||
$error = gettext("readEssLog() wasn't passed an input file.");
|
||||
Immunix::Ycp::y2error($error);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if ( open(ESS, "<$dir/$logFile") ) {
|
||||
|
||||
while (<ESS>) {
|
||||
|
||||
next if /^#/;
|
||||
chomp;
|
||||
next unless ($_);
|
||||
|
||||
my $rec = undef;
|
||||
|
||||
( $rec->{'host'}, $rec->{'startdate'}, $rec->{'enddate'}, $rec->{'sevHi'},
|
||||
$rec->{'sevMean'}, $rec->{'numRejects'},$rec->{'numEvents'} ) = split(/\,/, $_);
|
||||
|
||||
push(@essDb, $rec);
|
||||
}
|
||||
|
||||
close ESS;
|
||||
|
||||
} else {
|
||||
$error = sprintf(gettext("readEssLog() couldn't open %s"), $logFile);
|
||||
Immunix::Ycp::y2error($error);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
return (\@essDb);
|
||||
}
|
||||
|
||||
# Main
|
||||
################################################################################
|
||||
|
||||
while ( <STDIN> ) {
|
||||
|
||||
my ($command, $path, $args) = Immunix::Ycp::ParseCommand ($_);
|
||||
|
||||
if ($command && $path && $args) {
|
||||
|
||||
my $db = undef;
|
||||
|
||||
if ($args->{'essArch'} && $args->{'essArch'} == 1) {
|
||||
|
||||
if (! $args->{'single'} || $args->{'single'} != 1 ) {
|
||||
$db = readMultiEssLog($args);
|
||||
} else {
|
||||
$db = readEssLog($args);
|
||||
}
|
||||
|
||||
} else {
|
||||
$db = Immunix::Reports::getEssStats($args);
|
||||
}
|
||||
|
||||
Immunix::Ycp::ycpReturn( $db );
|
||||
|
||||
} else {
|
||||
my $error = sprintf( gettext("ag_logparse: Unknown instruction %s or argument: %s"), ycpGetCommand, ycpGetArgType);
|
||||
Immunix::Ycp::y2error("$error");
|
||||
Immunix::Ycp::ycpReturn($error);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
196
management/yastui/src/agents/ag_reports_parse
Executable file
|
@ -0,0 +1,196 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
################################################################################
|
||||
# ag_reports_parse
|
||||
#
|
||||
# - Generates list of archived reports
|
||||
# The 3 types of possible reports are:
|
||||
# 1) Security Incidents
|
||||
# 2) Applications Audits
|
||||
# 3) Executive Security Summaries
|
||||
#
|
||||
# Requires:
|
||||
#
|
||||
# Input (Required):
|
||||
# Parameter 'type' as in $args->{'type'}
|
||||
# of one of the following: 'archRep', 'audRep', 'essRep'
|
||||
#
|
||||
################################################################################
|
||||
my $Version='0.61';
|
||||
|
||||
use strict;
|
||||
use Immunix::Ycp;
|
||||
use Immunix::Reports;
|
||||
use POSIX;
|
||||
use Locale::gettext;
|
||||
|
||||
setlocale(LC_MESSAGES, "");
|
||||
textdomain("apparmor-utils");
|
||||
|
||||
# Writes out file to allow for multiple pages in YaST form
|
||||
# -For large number of entries in the array
|
||||
sub writePagingFile {
|
||||
|
||||
my $db = shift;
|
||||
|
||||
my $pagingFile = "/var/log/apparmor/reports/events.rpt";
|
||||
|
||||
if ( open(PF, ">$pagingFile") ) {
|
||||
|
||||
my $i = 1;
|
||||
my $page = 1;
|
||||
my $skip = 0;
|
||||
|
||||
print PF "Page $page\n";
|
||||
$page++;
|
||||
|
||||
for (@$db) {
|
||||
|
||||
# Order (for YaST): "host", "startdate", "enddate", "numRejects", "numEvents", "sevMean", "sevHi"
|
||||
print PF "$_->{'host'},$_->{'startdate'},$_->{'enddate'},$_->{'numRejects'},$_->{'numEvents'},$_->{'sevMean'},$_->{'sevHi'}\n";
|
||||
|
||||
if ( ($i % 100) == 0 && $skip == 0) {
|
||||
print PF "Page $page\n";
|
||||
$page++;
|
||||
$skip = 1;
|
||||
} else {
|
||||
$i++;
|
||||
$skip = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
close PF;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("ag_reports_parse: Couldn't open %s for writing."), $pagingFile));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub getFileList {
|
||||
|
||||
my $args = shift;
|
||||
|
||||
my $logDir = '/var/log/apparmor/reports-archived';
|
||||
|
||||
if ( $args->{'repPath'} && -d $args->{'repPath'} ) {
|
||||
$logDir = $args->{'repPath'};
|
||||
}
|
||||
|
||||
my @rawList = ();
|
||||
my @presortList = ();
|
||||
my @dirList = ();
|
||||
my $error = undef;
|
||||
|
||||
# Create list of subdomain activation prospects from Old logfiles
|
||||
if ( opendir(LDIR, $logDir) ) {
|
||||
|
||||
if ( $args->{'type'} eq "sirRep" || $args->{'type'} eq "archRep" ) {
|
||||
#@rawList = grep { /Security.Incident/ && -f "$logDir/$_" } readdir(LDIR);
|
||||
|
||||
while ( my $file = readdir(LDIR) ) {
|
||||
if ( $file !~ /^\.|\.$/ && $file !~ /Applications.Audit/ && $file !~ /Executive.Security/) {
|
||||
push(@rawList, $file);
|
||||
}
|
||||
}
|
||||
|
||||
} elsif ( $args->{'type'} eq "audRep" ) {
|
||||
#@rawList = grep { /.aud.csv/ && -f "$logDir/$_" } readdir(LDIR);
|
||||
@rawList = grep { /Applications.Audit/ && -f "$logDir/$_" } readdir(LDIR);
|
||||
} elsif ( $args->{'type'} eq "essRep" ) {
|
||||
#@rawList = grep { /.ess.csv/ && -f "$logDir/$_" } readdir(LDIR);
|
||||
@rawList = grep { /Executive.Security/ && -f "$logDir/$_" } readdir(LDIR);
|
||||
}
|
||||
|
||||
closedir LDIR;
|
||||
|
||||
# remove non csv file types
|
||||
@rawList = grep(/csv$/, @rawList);
|
||||
|
||||
for (@rawList) {
|
||||
my $ref = undef;
|
||||
$ref->{'name'} = "$_";
|
||||
#$ref->{'time'} = (stat("$logDir/$_"))[10];
|
||||
my $file = "$_";
|
||||
$file =~ s/\.\d+\.\w+$//;
|
||||
my ($junk, $date) = split(/\-/, $file, 2);
|
||||
$date =~ s/\./\:/g;
|
||||
$ref->{'time'} = $date;
|
||||
|
||||
push(@presortList, $ref);
|
||||
}
|
||||
|
||||
@dirList = sort { $a->{'time'} cmp $b->{'time'} } (@presortList);
|
||||
|
||||
my $numels = scalar(@dirList);
|
||||
|
||||
if (@dirList > 0) {
|
||||
#writePagingFile(\@dirList);
|
||||
return \@dirList;
|
||||
} else {
|
||||
Immunix::Ycp::y2error(gettext("ag_reports_parse: No archived reports found."));
|
||||
return $error;
|
||||
}
|
||||
|
||||
} else {
|
||||
$error = sprintf(gettext("ag_reports_parse: Can't open directory %s: %s"), $logDir, $!);
|
||||
Immunix::Ycp::y2error($error);
|
||||
return $error;
|
||||
}
|
||||
}
|
||||
|
||||
# Main
|
||||
################################################################################
|
||||
|
||||
while ( <STDIN> ) {
|
||||
|
||||
my ($command, $path, $args) = Immunix::Ycp::ParseCommand ($_);
|
||||
|
||||
if ( $command && $path && $args ) {
|
||||
|
||||
my $error = undef;
|
||||
|
||||
if ( $args->{'checkDb'} && $args->{'checkDb'} == 1 ) {
|
||||
my $check = Immunix::Reports::checkEventDb();
|
||||
Immunix::Ycp::ycpReturn( $check );
|
||||
|
||||
} elsif ( $args->{'getLastPage'} && $args->{'getLastPage'} == 1 ) {
|
||||
|
||||
my $ref = undef;
|
||||
$ref->{'numPages'} = Immunix::Reports::getNumPages($args);
|
||||
Immunix::Ycp::ycpReturn( $ref );
|
||||
|
||||
} elsif ( $args->{'checkFile'} && $args->{'checkFile'} == 1 ) {
|
||||
my $fileCheck = Immunix::Reports::checkFileExists("$args->{'file'}");
|
||||
Immunix::Ycp::ycpReturn( $fileCheck );
|
||||
|
||||
} else {
|
||||
my $dirList = getFileList($args);
|
||||
Immunix::Ycp::ycpReturn( $dirList );
|
||||
}
|
||||
|
||||
} else {
|
||||
my $error = sprintf( gettext("ag_reports_parse: Unknown instruction %s or argument: %s"), ycpGetCommand, ycpGetArgType);
|
||||
Immunix::Ycp::y2error("$error");
|
||||
Immunix::Ycp::ycpReturn($error);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
|
||||
|
690
management/yastui/src/agents/ag_reports_sched
Executable file
|
@ -0,0 +1,690 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
################################################################################
|
||||
# ag_reports_sched
|
||||
#
|
||||
# - Adds/Deletes/Edits Scheduled Subdomain Event Reports (cron)
|
||||
#
|
||||
# Requires:
|
||||
# - /usr/lib/immunix/SubDomain/perl/Immunix/Events.pm
|
||||
# - /usr/lib/immunix/SubDomain/perl/Immunix/Reports.pm
|
||||
#
|
||||
# Uses:
|
||||
# -/etc/apparmor/reports.crontab
|
||||
# -/etc/apparmor/reports.conf
|
||||
#
|
||||
# Input (Conditional/Optional):
|
||||
# -Report Name
|
||||
# -Start Date|End Date (Year, Month, Day, Time)
|
||||
# -Program Name
|
||||
# -Profile Name
|
||||
# -PID
|
||||
# -Severity Level
|
||||
# -Denied Resources
|
||||
# -SD Mode
|
||||
# -Mode
|
||||
#
|
||||
################################################################################
|
||||
|
||||
my $Version="0.97";
|
||||
|
||||
use strict;
|
||||
use Immunix::Ycp;
|
||||
use Immunix::Reports;
|
||||
use POSIX;
|
||||
use Locale::gettext;
|
||||
|
||||
setlocale(LC_MESSAGES, "");
|
||||
textdomain("apparmor-utils");
|
||||
|
||||
sub debug {
|
||||
|
||||
my $db = shift;
|
||||
|
||||
for (@$db) {
|
||||
my $rec = $_;
|
||||
for (sort keys(%$rec) ) {
|
||||
print "$_ is $rec->{$_} ";
|
||||
}
|
||||
}
|
||||
|
||||
print "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Activate the cron jobs
|
||||
sub setCronTab {
|
||||
|
||||
my $cronFile = '/etc/apparmor/reports.crontab';
|
||||
|
||||
if ( -e $cronFile ) {
|
||||
#system('/usr/bin/crontab', '-u root', "$cronFile");
|
||||
system("/usr/bin/crontab -u root $cronFile");
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't find %s. Unable to create crontab. Exiting."), $cronFile));
|
||||
exit 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# returns ref to active filters for the specific SIR report
|
||||
# This is the same routine as in /usr/bin/reportgen.pl -- should move both to Reports.pm
|
||||
sub getFilters {
|
||||
|
||||
my $repName = shift;
|
||||
|
||||
my $filts = undef;
|
||||
my $schedConf = '/etc/apparmor/reports.conf';
|
||||
my $regExp = '(prog|profile|pid|resource|severity|sdmode|mode)';
|
||||
|
||||
my $allConf = Immunix::Reports::getXmlReport($repName);
|
||||
|
||||
# Create filters reference
|
||||
for my $ref ( keys(%$allConf) ) {
|
||||
if ( $ref =~ /$regExp/ ) {
|
||||
$filts->{$ref} = $allConf->{$ref};
|
||||
delete($allConf->{$ref});
|
||||
}
|
||||
}
|
||||
|
||||
# Clean hash of useless refs
|
||||
for (sort keys(%$filts) ) {
|
||||
if ($filts->{$_} eq "-") {
|
||||
delete($filts->{$_});
|
||||
}
|
||||
}
|
||||
|
||||
return $filts;
|
||||
}
|
||||
|
||||
# checks crontab file for matching report name
|
||||
sub findDupeReportName {
|
||||
|
||||
my $name = shift;
|
||||
my $dupe = '0';
|
||||
my @db = ();
|
||||
|
||||
my $schedCron = '/etc/apparmor/reports.crontab';
|
||||
|
||||
if ( open (CRON, "<$schedCron") ) {
|
||||
|
||||
while(<CRON>) {
|
||||
chomp;
|
||||
my ($repname) = (split(/reportgen\.pl\s+/, $_))[1];
|
||||
push(@db, $repname);
|
||||
}
|
||||
|
||||
close CRON;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't open %s."), $schedCron));
|
||||
exit 1;
|
||||
}
|
||||
|
||||
for (@db) {
|
||||
if ( $name eq "$_" || "\"$name\"" eq "$_" ) {
|
||||
$dupe = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $dupe;
|
||||
}
|
||||
|
||||
sub addCron {
|
||||
|
||||
my $args = shift;
|
||||
|
||||
#my $schedCron = '/etc/cron.d/reportsched';
|
||||
my $schedCron = '/etc/apparmor/reports.crontab';
|
||||
my $repScript = "/usr/bin/reportgen.pl";
|
||||
|
||||
if ( open (CRON, ">>$schedCron") ) {
|
||||
|
||||
my $mon = '*';
|
||||
|
||||
# crontab key
|
||||
############################################################
|
||||
# minute 0-59
|
||||
# hour 0-23
|
||||
# day of month 1-31
|
||||
# month 1-12 (or names, see below)
|
||||
# day of week 0-7 (0 or 7 is Sun, or use names)
|
||||
############################################################
|
||||
|
||||
my $sched = "$args->{'mins'} $args->{'hour'} $args->{'monthdate'} $mon $args->{'weekday'}";
|
||||
|
||||
#print CRON "$sched root $repScript $args->{'name'}\n";
|
||||
print CRON "$sched $repScript \"$args->{'name'}\"\n";
|
||||
|
||||
close CRON;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't open %s."), $schedCron));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub addConf {
|
||||
|
||||
my $args = shift;
|
||||
my $schedConf = '/etc/apparmor/reports.conf';
|
||||
my $newSchedConf = '/var/log/apparmor/reports/reports.conf';
|
||||
|
||||
if ( ! $args->{'csv'} ) { $args->{'csv'} = '0'; }
|
||||
if ( ! $args->{'html'} ) { $args->{'html'} = '0'; }
|
||||
|
||||
if ( open (OCF, "<$schedConf") ) {
|
||||
|
||||
if ( open (NCF, ">$newSchedConf") ) {
|
||||
|
||||
# pre-process filters for GUI - UGLY
|
||||
for ($args->{'prog'},$args->{'prof'},$args->{'pid'},$args->{'sev'},
|
||||
$args->{'res'},$args->{'sdmode'},$args->{'mode'}) {
|
||||
|
||||
$_ =~ s/\s+//g;
|
||||
|
||||
if ( ! $_ || $_ eq "NA" || $_ eq "" || $_ eq "All" ) {
|
||||
$_ = "-";
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $_ || $_ eq "NA" || $_ eq "" || $_ eq "All" ) {
|
||||
$_ = "-";
|
||||
}
|
||||
|
||||
# pre-write the longer entries
|
||||
my $expPath = $args->{'expPath'} || '/var/log/apparmor/reports-archived';
|
||||
$expPath = "<exportpath>$expPath<\/exportpath>";
|
||||
my $expType = "<exporttype csv=\"$args->{'csv'}\" html=\"$args->{'html'}\" \/>";
|
||||
|
||||
my $email = "<email addr1=\"$args->{'email1'}\" addr2=\"$args->{'email2'}\" " .
|
||||
"addr3=\"$args->{'email3'}\" \/>";
|
||||
|
||||
# copy the old stuff over
|
||||
while (<OCF>) {
|
||||
unless ( $_ =~ /\<\/apparmor\>/ || $_ eq "\n" ) {
|
||||
print NCF "$_";
|
||||
}
|
||||
}
|
||||
|
||||
# add the new
|
||||
print NCF "\t<report>\n";
|
||||
print NCF "\t\t<name>$args->{'name'}</name>\n";
|
||||
print NCF "\t\t<prog>$args->{'prog'}</prog>\n";
|
||||
print NCF "\t\t<profile>$args->{'prof'}</profile>\n";
|
||||
print NCF "\t\t<pid>$args->{'pid'}</pid>\n";
|
||||
print NCF "\t\t<severity>$args->{'sev'}</severity>\n";
|
||||
print NCF "\t\t<resource>$args->{'res'}</resource>\n";
|
||||
print NCF "\t\t<sdmode>$args->{'sdmode'}</sdmode>\n";
|
||||
print NCF "\t\t<mode>$args->{'mode'}</mode>\n";
|
||||
print NCF "\t\t$expPath\n";
|
||||
print NCF "\t\t$expType\n";
|
||||
print NCF "\t\t$email\n";
|
||||
print NCF "\t\t<time>1104566401</time>\n"; # '1104566401' is default last run time
|
||||
print NCF "\t</report>\n";
|
||||
print NCF "</apparmor>\n";
|
||||
|
||||
close NCF;
|
||||
|
||||
} else {
|
||||
my $error = sprintf(gettext("Couldn't open %s. Unable to add report: %s"), $newSchedConf, $args->{'name'});
|
||||
Immunix::Ycp::y2error($error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
close OCF;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't open %s."), $schedConf));
|
||||
return 1;
|
||||
}
|
||||
|
||||
Immunix::Reports::updateFiles($schedConf,$newSchedConf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
sub addReport {
|
||||
|
||||
my $args = shift;
|
||||
|
||||
my $dupe = findDupeReportName("$args->{'name'}");
|
||||
|
||||
if ($dupe == 1) {
|
||||
my $error = sprintf(gettext("Duplicate report name not allowed. Didn't schedule new report: %s"), $args->{'name'});
|
||||
Immunix::Ycp::y2error("$error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Translate filters to cronspeak
|
||||
if ( ! $args->{'hour'} || $args->{'hour'} eq "-" || $args->{'hour'} eq '*' ) { $args->{'hour'} = "0"; }
|
||||
if ( ! $args->{'mins'} || $args->{'mins'} eq "-" || $args->{'mins'} eq '*' ) { $args->{'mins'} = "0"; }
|
||||
if ( ! $args->{'weekday'} || $args->{'weekday'} eq "-" ) { $args->{'weekday'} = "*"; }
|
||||
if ( ! $args->{'monthdate'} || $args->{'monthdate'} eq "-" ) { $args->{'monthdate'} = "*"; }
|
||||
|
||||
my $error = addCron($args);
|
||||
setCronTab();
|
||||
|
||||
if ($error == 0) {
|
||||
$error = addConf($args);
|
||||
if ($error != 0) { Immunix::Ycp::y2error($error); }
|
||||
} else {
|
||||
Immunix::Ycp::y2error($error);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# removes cron job related to report
|
||||
sub delCron {
|
||||
|
||||
my $name = shift;
|
||||
#my $schedCron = '/etc/cron.d/reportsched';
|
||||
my $schedCron = '/etc/apparmor/reports.crontab';
|
||||
my $newSchedCron = '/var/log/apparmor/reports/reportsched';
|
||||
if ( open(OCRON, "<$schedCron") ) {
|
||||
|
||||
if ( open(NCRON, ">$newSchedCron") ) {
|
||||
|
||||
while (<OCRON>) {
|
||||
chomp;
|
||||
my ($repname) = (split(/reportgen\.pl\s+/, $_))[1];
|
||||
next if ($repname eq "\"$name\"");
|
||||
print NCRON "$_\n";
|
||||
}
|
||||
|
||||
close NCRON;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't open %s."), $newSchedCron));
|
||||
return 1;
|
||||
}
|
||||
|
||||
close OCRON;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't open %s."), $schedCron));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Immunix::Reports::updateFiles($schedCron,$newSchedCron);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# deletes a report entry from reports.conf
|
||||
sub delConf {
|
||||
|
||||
my $repName = shift;
|
||||
my $schedConf = '/etc/apparmor/reports.conf';
|
||||
my $newSchedConf = '/var/log/apparmor/reports/reports.conf';
|
||||
|
||||
my @repList = ();
|
||||
my @thisRep = ();
|
||||
my $writeFlag = 1;
|
||||
|
||||
if ( open(OCF, "<$schedConf") ) {
|
||||
|
||||
if ( open(NCF, ">$newSchedConf") ) {
|
||||
|
||||
while (<OCF>) {
|
||||
|
||||
my $line = $_;
|
||||
|
||||
# Start array storage
|
||||
if ( $line =~ m/\<report\>/ ) {
|
||||
@thisRep = ();
|
||||
}
|
||||
|
||||
push(@thisRep, $line);
|
||||
chomp($line);
|
||||
|
||||
# End array storage
|
||||
if ( $line =~ m/\<\/report\>/ ) {
|
||||
if ( $writeFlag == 1 ) {
|
||||
push (@repList, @thisRep);
|
||||
}
|
||||
$writeFlag = 1; # reset flag -- we want to write by default
|
||||
}
|
||||
|
||||
# Match names to determine flag state
|
||||
if ( $line =~ m/\<name\>/ ) {
|
||||
my $curName = $line;
|
||||
$curName =~ s/(^\s*|\s*$)//g;
|
||||
$curName =~ s/((\<|\<\/)name\>)//g; #/<name>(\w+)</name>/;
|
||||
if ( $curName eq $repName ) { $writeFlag = 0; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( scalar(@repList) > 0 ) {
|
||||
print NCF "<apparmor>\n";
|
||||
print NCF "@repList";
|
||||
print NCF "</apparmor>\n";
|
||||
}
|
||||
|
||||
close NCF;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't open %s."), $newSchedConf));
|
||||
return 1;
|
||||
}
|
||||
|
||||
close OCF;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't open %s."), $schedConf));
|
||||
return 1;
|
||||
}
|
||||
|
||||
Immunix::Reports::updateFiles($schedConf,$newSchedConf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub delReport {
|
||||
|
||||
my $args = shift;
|
||||
|
||||
my $name = $args->{'name'};
|
||||
|
||||
my $error = delCron($name);
|
||||
|
||||
if ($error == 0) {
|
||||
$error = delConf($name);
|
||||
if ($error != 0) { Immunix::Ycp::y2error($error); }
|
||||
} else {
|
||||
Immunix::Ycp::y2error($error);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
setCronTab();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# returns list of report cron jobs
|
||||
sub parseCron {
|
||||
|
||||
my $args = shift;
|
||||
my $error = undef;
|
||||
my @db = ();
|
||||
|
||||
#my $schedCron = '/etc/cron.d/reportsched';
|
||||
my $schedCron = '/etc/apparmor/reports.crontab';
|
||||
|
||||
if ( open (CRON, "<$schedCron") ) {
|
||||
|
||||
my $junkMon = undef;
|
||||
#my $junkRt = undef;
|
||||
my $junkScript = undef;
|
||||
|
||||
while (<CRON>) {
|
||||
|
||||
#next if /^#\s*\w*/;
|
||||
chomp;
|
||||
my $rec = undef;
|
||||
my @name = undef;
|
||||
|
||||
# Day of Month, Day of Week, Hour, Minute : report-to-execute
|
||||
# * * * * root /usr/bin/reportgen.pl <sir|aud|name-of-sir>
|
||||
|
||||
# crontab key
|
||||
############################################################
|
||||
# minute 0-59
|
||||
# hour 0-23
|
||||
# day of month 1-31
|
||||
# month 1-12 (or names, see below)
|
||||
# day of week 0-7 (0 or 7 is Sun, or use names)
|
||||
############################################################
|
||||
|
||||
#($rec->{'mins'}, $rec->{'hour'}, $rec->{'mday'}, $junkMon, $rec->{'wday'}, $junkRt, $junkScript, $rec->{'name'}) = split (/\s+/, $_);
|
||||
($rec->{'mins'}, $rec->{'hour'}, $rec->{'mday'}, $junkMon, $rec->{'wday'},
|
||||
$junkScript, @name) = split (/\s+/, $_);
|
||||
#$junkRt, $junkScript, @name) = split (/\s+/, $_);
|
||||
|
||||
if ($rec->{'mins'} eq "*") { $rec->{'mins'} = "-"; }
|
||||
if ($rec->{'hour'} eq "*") { $rec->{'hour'} = "-"; }
|
||||
if ($rec->{'mday'} eq "*") { $rec->{'mday'} = "-"; }
|
||||
if ($rec->{'wday'} eq "*") { $rec->{'wday'} = "-"; }
|
||||
$rec->{'name'} = join( " ", @name);
|
||||
if ($rec->{'name'} =~ /\"/) { $rec->{'name'} =~ s/\"//g; }
|
||||
|
||||
push(@db, $rec);
|
||||
}
|
||||
|
||||
close CRON;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't open %s."), $schedCron));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return \@db;
|
||||
}
|
||||
|
||||
# returns hash refs of a single (line) report
|
||||
sub getCron {
|
||||
|
||||
my $args = shift;
|
||||
my $error = undef;
|
||||
my @db = ();
|
||||
my $rep = undef;
|
||||
|
||||
#my $schedCron = '/etc/cron.d/reportsched';
|
||||
my $schedCron = '/etc/apparmor/reports.crontab';
|
||||
|
||||
if ( open (CRON, "<$schedCron") ) {
|
||||
|
||||
my $junkMon = undef;
|
||||
#my $junkRt = undef;
|
||||
my $junkScript = undef;
|
||||
|
||||
#if ($args->{'name'} && $args->{'name'} =~ m/\s+/) { $args->{'name'} = "\"$args->{'name'}\""; }
|
||||
|
||||
while (<CRON>) {
|
||||
|
||||
#next if /^#\s*\w*/;
|
||||
chomp;
|
||||
my $rec = undef;
|
||||
my @name = ();
|
||||
|
||||
# Day of Month, Day of Week, Hour, Minute : report-to-execute
|
||||
# * * * * root /usr/bin/reportgen.pl <sir|aud|name-of-sir>
|
||||
# * * * * /usr/bin/reportgen.pl <sir|aud|name-of-sir>
|
||||
|
||||
# crontab key
|
||||
############################################################
|
||||
# minute 0-59
|
||||
# hour 0-23
|
||||
# day of month 1-31
|
||||
# month 1-12 (or names, see below)
|
||||
# day of week 0-7 (0 or 7 is Sun, or use names)
|
||||
############################################################
|
||||
|
||||
($rec->{'mins'}, $rec->{'hour'}, $rec->{'mday'}, $junkMon,
|
||||
#$rec->{'wday'}, $junkRt, $junkScript, @name ) = split (/\s+/, $_);
|
||||
$rec->{'wday'}, $junkScript, @name ) = split (/\s+/, $_);
|
||||
|
||||
if ($rec->{'mins'} eq "*") { $rec->{'mins'} = "-"; }
|
||||
if ($rec->{'hour'} eq "*") { $rec->{'hour'} = "-"; }
|
||||
if ($rec->{'mday'} eq "*") { $rec->{'mday'} = "-"; }
|
||||
if ($rec->{'wday'} eq "*") { $rec->{'wday'} = "-"; }
|
||||
$rec->{'name'} = join( " ", @name);
|
||||
|
||||
if ($rec->{'name'} eq "\"$args->{'name'}\"" ) {
|
||||
$rec->{'name'} =~ s/\"//g;
|
||||
$rep = $rec;
|
||||
}
|
||||
}
|
||||
|
||||
close CRON;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't open %s."), $schedCron));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return $rep;
|
||||
}
|
||||
|
||||
sub editCron {
|
||||
|
||||
my $args = shift;
|
||||
#my $schedCron = '/etc/cron.d/reportsched';
|
||||
my $schedCron = '/etc/apparmor/reports.crontab';
|
||||
my $newCron = '/var/log/apparmor/reports/reportsched';
|
||||
my $repScript = "/usr/bin/reportgen.pl";
|
||||
|
||||
if ( open(CRON, "<$schedCron") ) {
|
||||
|
||||
if ( open (NCRON, ">$newCron") ) {
|
||||
|
||||
my $mon = '*';
|
||||
|
||||
if ( ! $args->{'hour'} || $args->{'hour'} eq "-" || $args->{'hour'} eq '*') { $args->{'hour'} = '0'; }
|
||||
if ( ! $args->{'mins'} || $args->{'mins'} eq "-" || $args->{'mins'} eq '*' ) { $args->{'mins'} = '0'; }
|
||||
if ( ! $args->{'monthdate'} || $args->{'monthdate'} eq "-" ) { $args->{'monthdate'} = '*'; }
|
||||
if ( ! $args->{'weekday'} || $args->{'weekday'} eq "-" ) { $args->{'weekday'} = '*'; }
|
||||
|
||||
while (<CRON>) {
|
||||
chomp;
|
||||
my ($repname) = (split(/reportgen\.pl\s+/, $_))[1];
|
||||
$repname =~ s/^\s+//;
|
||||
$repname =~ s/\s+$//;
|
||||
if ($repname eq "\"$args->{'name'}\"") {
|
||||
my $sched = "$args->{'mins'} $args->{'hour'} $args->{'monthdate'} $mon $args->{'weekday'}";
|
||||
$_ = "$sched $repScript \"$args->{'name'}\"";
|
||||
}
|
||||
print NCRON "$_\n";
|
||||
}
|
||||
|
||||
close NCRON;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't open %s. No changes performed."), $newCron));
|
||||
return 1;
|
||||
}
|
||||
|
||||
close CRON;
|
||||
|
||||
} else {
|
||||
Immunix::Ycp::y2error(sprintf(gettext("Couldn't open %s. No changes performed."), $schedCron));
|
||||
return 1;
|
||||
}
|
||||
|
||||
my $error = Immunix::Reports::updateFiles($schedCron,$newCron);
|
||||
|
||||
if ($error == 1) {
|
||||
exit 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
# sloppy -- should redo
|
||||
sub editConf {
|
||||
|
||||
my $args = shift;
|
||||
|
||||
if ( ! $args->{'csv'} ) { $args->{'csv'} = '0'; }
|
||||
if ( ! $args->{'html'} ) { $args->{'html'} = '0'; }
|
||||
|
||||
delConf($args->{'name'});
|
||||
addConf($args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub editSched {
|
||||
|
||||
my $args = shift;
|
||||
editCron($args);
|
||||
setCronTab();
|
||||
editConf($args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Main
|
||||
################################################################################
|
||||
|
||||
while ( <STDIN> ) {
|
||||
|
||||
my ($command, $path, $args) = Immunix::Ycp::ParseCommand ($_);
|
||||
|
||||
if ( $command && $path && $args ) {
|
||||
|
||||
my $db = undef;
|
||||
|
||||
if ( $args->{'name'} =~ /Edit\s+(\w.+)\s+Sched/ ) {
|
||||
$args->{'name'} = $1;
|
||||
}
|
||||
|
||||
# Parse sdmode & mode labels
|
||||
if ( $args->{'sdmode'} ) {
|
||||
$args->{'sdmode'} =~ s/\&//g;
|
||||
$args->{'sdmode'} =~ s/\://g;
|
||||
$args->{'sdmode'} =~ s/\s//g;
|
||||
$args->{'sdmode'} =~ s/AccessType//g;
|
||||
}
|
||||
if ( $args->{'mode'} ) {
|
||||
$args->{'mode'} =~ s/\&//g;
|
||||
$args->{'mode'} =~ s/Mode\://g;
|
||||
$args->{'mode'} =~ s/\s//g;
|
||||
}
|
||||
|
||||
if ( $args->{'getdupe'} && $args->{'getdupe'} == 1) {
|
||||
|
||||
$db = findDupeReportName("$args->{'name'}");
|
||||
|
||||
}
|
||||
if ($args->{'getcron'} && $args->{'getcron'} == 1) {
|
||||
$db = parseCron($args); # Return list of all scheduled report crons
|
||||
} elsif ( $args->{'getrep'} && $args->{'getrep'} ==1 ) {
|
||||
$db = getCron($args);
|
||||
} elsif ( $args->{'getconf'} && $args->{'getconf'} ==1 ) {
|
||||
$db = Immunix::Reports::getXmlReport($args->{'name'});
|
||||
} elsif ( $args->{'setconf'} && $args->{'setconf'} ==1 ) {
|
||||
editSched($args);
|
||||
} elsif ( $args->{'add'} && $args->{'add'} == 1) {
|
||||
addReport($args);
|
||||
} elsif ( $args->{'del'} && $args->{'del'} == 1) {
|
||||
delReport($args);
|
||||
} elsif ( $args->{'getfilters'} && $args->{'getfilters'} == 1) {
|
||||
$db = getFilters($args);
|
||||
}
|
||||
|
||||
if ( defined($db) ) {
|
||||
Immunix::Ycp::ycpReturn( $db );
|
||||
} else {
|
||||
Immunix::Ycp::ycpReturn( "true" );
|
||||
}
|
||||
|
||||
} else {
|
||||
my $error = sprintf( gettext("ag_reports_sched: Unknown instruction %s or arg: %s"), ycpGetCommand, ycpGetArgType);
|
||||
Immunix::Ycp::ycpReturn($error);
|
||||
}
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
|
186
management/yastui/src/agents/ag_sd_config
Executable file
|
@ -0,0 +1,186 @@
|
|||
#!/usr/bin/perl -w
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
################################################################################
|
||||
# ag_sd_config
|
||||
#
|
||||
# Version 0.51
|
||||
################################################################################
|
||||
|
||||
use Immunix::Ycp;
|
||||
use Immunix::Reports;
|
||||
use strict;
|
||||
use Data::Dumper;
|
||||
|
||||
# Subroutines
|
||||
################################################################################
|
||||
|
||||
sub setSubdomain {
|
||||
|
||||
my $action = shift;
|
||||
my $errmsg = "";
|
||||
my $lines = 0;
|
||||
if ($action eq "enable") {
|
||||
if (-e "/sbin/rcapparmor") {
|
||||
open(RUN, "/sbin/rcapparmor start 2>&1 |");
|
||||
} else {
|
||||
open(RUN, "/sbin/rcsubdomain start 2>&1 |");
|
||||
}
|
||||
while (<RUN>) {
|
||||
if (/FATAL:(.*)/) {
|
||||
$errmsg = $1;
|
||||
}
|
||||
}
|
||||
close(RUN);
|
||||
if (-f "/etc/init.d/boot.apparmor") {
|
||||
system("/sbin/insserv boot.apparmor");
|
||||
} else {
|
||||
system("/sbin/insserv boot.subdomain");
|
||||
}
|
||||
if (-f "/etc/init.d/aaeventd") {
|
||||
system("/sbin/rcaaeventd start");
|
||||
system("/sbin/insserv aaeventd");
|
||||
}
|
||||
} else {
|
||||
if (-e "/sbin/rcapparmor") {
|
||||
open(RUN, "/sbin/rcapparmor stop 2>&1 |");
|
||||
} else {
|
||||
open(RUN, "/sbin/rcsubdomain stop 2>&1 |");
|
||||
}
|
||||
while (<RUN>) {
|
||||
if (/FATAL:(.*)/) {
|
||||
$errmsg = $1;
|
||||
}
|
||||
}
|
||||
close(RUN);
|
||||
if (-f "/etc/init.d/boot.apparmor") {
|
||||
system("/sbin/insserv -r boot.apparmor");
|
||||
} else {
|
||||
system("/sbin/insserv -r boot.subdomain");
|
||||
}
|
||||
if (-f "/etc/init.d/aaeventd") {
|
||||
system("/sbin/rcaaeventd stop");
|
||||
system("/sbin/insserv -e aaeventd");
|
||||
}
|
||||
}
|
||||
return $errmsg;
|
||||
}
|
||||
|
||||
sub setNotify {
|
||||
|
||||
my $action = shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub setLearningMode {
|
||||
|
||||
my $action = shift;
|
||||
my $rcscript = -f "/sbin/rcapparmor" ? "/sbin/rcapparmor"
|
||||
: "/sbin/rcsubdomain";
|
||||
|
||||
if ($action eq "enable") {
|
||||
system("$rcscript", "stop");
|
||||
system("$rcscript", "complain");
|
||||
} else {
|
||||
system("$rcscript". "stop");
|
||||
system("$rcscript", "start");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub setNotifySettings {
|
||||
my $config = shift;
|
||||
|
||||
Immunix::Reports::enableEventD();
|
||||
open(CFG, "> /etc/apparmor/notify.cfg") or die "can't write config info: $!";
|
||||
if($config->{enable_terse} eq "yes") {
|
||||
# if we didn't get passed a valid frequency, default to off
|
||||
$config->{terse_freq} ||= 0;
|
||||
$config->{terse_level} ||= 0;
|
||||
# default to including unknown events if we didn't get passed that setting
|
||||
$config->{terse_unknown} = 1 unless defined $config->{terse_unknown};
|
||||
print CFG "terse_freq $config->{terse_freq}\n";
|
||||
print CFG "terse_email $config->{terse_email}\n";
|
||||
print CFG "terse_level $config->{terse_level}\n";
|
||||
print CFG "terse_unknown $config->{terse_unknown}\n";
|
||||
}
|
||||
if($config->{enable_summary} eq "yes") {
|
||||
# if we didn't get passed a valid frequency, default to off
|
||||
$config->{summary_freq} ||= 0;
|
||||
$config->{summary_level} ||= 0;
|
||||
# default to including unknown events if we didn't get passed that setting
|
||||
$config->{summary_unknown} = 1 unless defined $config->{summary_unknown};
|
||||
print CFG "summary_freq $config->{summary_freq}\n";
|
||||
print CFG "summary_email $config->{summary_email}\n";
|
||||
print CFG "summary_level $config->{summary_level}\n";
|
||||
print CFG "summary_unknown $config->{summary_unknown}\n";
|
||||
}
|
||||
if($config->{enable_verbose} eq "yes") {
|
||||
# if we didn't get passed a valid frequency, default to off
|
||||
$config->{verbose_freq} ||= 0;
|
||||
$config->{verbose_level} ||= 0;
|
||||
# default to including unknown events if we didn't get passed that setting
|
||||
$config->{verbose_unknown} = 1 unless defined $config->{verbose_unknown};
|
||||
print CFG "verbose_freq $config->{verbose_freq}\n";
|
||||
print CFG "verbose_email $config->{verbose_email}\n";
|
||||
print CFG "verbose_level $config->{verbose_level}\n";
|
||||
print CFG "verbose_unknown $config->{verbose_unknown}\n";
|
||||
}
|
||||
close(CFG);
|
||||
}
|
||||
|
||||
# Main
|
||||
################################################################################
|
||||
|
||||
|
||||
while ( <STDIN> ) {
|
||||
|
||||
my ($command, $path, $argument) = Immunix::Ycp::ParseCommand ($_);
|
||||
Immunix::Ycp::y2debug ("command: $command, path: $path");
|
||||
|
||||
my $result = undef;
|
||||
my $action = undef;
|
||||
|
||||
if ( $command && $path && $argument ) {
|
||||
|
||||
if(ref($argument) eq "HASH" && $argument->{"sd-set-notify"}) {
|
||||
setNotifySettings($argument);
|
||||
Immunix::Ycp::Return("true");
|
||||
next;
|
||||
}
|
||||
|
||||
($action) = (split(/:/, $argument))[1];
|
||||
|
||||
Immunix::Ycp::y2milestone ("ag_sd_config=> Arg: $argument, Action: $action");
|
||||
|
||||
if ( $argument =~ /subdomain/ ) {
|
||||
$result = setSubdomain($action);
|
||||
} elsif ( $argument =~ /learning/ ) {
|
||||
setLearningMode($action);
|
||||
} elsif ( $argument eq 'sd-notify') {
|
||||
setNotify($action);
|
||||
}
|
||||
Immunix::Ycp::y2milestone ("ag_sd_config=> DONE Arg: $argument, Action: $action");
|
||||
if ( $result ) {
|
||||
Immunix::Ycp::Return( $result );
|
||||
} else {
|
||||
Immunix::Ycp::Return("true");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
|
||||
|
122
management/yastui/src/agents/ag_subdomain
Executable file
|
@ -0,0 +1,122 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
|
||||
################################################################################
|
||||
# ag_subdomain
|
||||
#
|
||||
# Version 0.61
|
||||
################################################################################
|
||||
|
||||
use strict;
|
||||
use Immunix::Ycp;
|
||||
use Immunix::SubDomain;
|
||||
use Data::Dumper;
|
||||
|
||||
# Subroutines
|
||||
################################################################################
|
||||
|
||||
sub getSubdomainStatus {
|
||||
|
||||
my $sdStatus = "disabled";
|
||||
|
||||
# Ok check that there are profiles loaded to
|
||||
# determine status
|
||||
my $mountpoint = Immunix::SubDomain::check_for_subdomain();
|
||||
if ( $mountpoint ) {
|
||||
open( PROFILES, "cat $mountpoint/profiles|" );
|
||||
while (<PROFILES>) {
|
||||
# Ensure we have loaded profiles
|
||||
# not just a loaded module
|
||||
if ( /\// ) {
|
||||
$sdStatus = "enabled";
|
||||
last;
|
||||
}
|
||||
}
|
||||
close PROFILES;
|
||||
}
|
||||
return $sdStatus;
|
||||
}
|
||||
|
||||
sub getNotifySettings {
|
||||
|
||||
my $config = { };
|
||||
if(open(CFG, "/etc/apparmor/notify.cfg")) {
|
||||
while(<CFG>) {
|
||||
chomp;
|
||||
$config->{$1} = $2 if /^(\S+)\s+(.+)\s*$/;
|
||||
}
|
||||
close(CFG);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
|
||||
sub getNotifyStatus {
|
||||
|
||||
my $config = getNotifySettings();
|
||||
|
||||
my $noteStatus = "disabled";
|
||||
|
||||
if($config->{terse_freq} && $config->{terse_freq} != 0) {
|
||||
$noteStatus = "enabled";
|
||||
} elsif($config->{summary_freq} && $config->{summary_freq} != 0) {
|
||||
$noteStatus = "enabled";
|
||||
} elsif($config->{verbose_freq} && $config->{verbose_freq} != 0) {
|
||||
$noteStatus = "enabled";
|
||||
}
|
||||
|
||||
return $noteStatus;
|
||||
}
|
||||
|
||||
# Main
|
||||
################################################################################
|
||||
|
||||
|
||||
my $line = <STDIN>;
|
||||
|
||||
my ($command, $path, $argument) = Immunix::Ycp::ParseCommand($line);
|
||||
|
||||
my $result = undef;
|
||||
my $donereturn = 0;
|
||||
if ( $command && $path && $argument ) {
|
||||
if ( $argument eq 'sd-all') {
|
||||
my %hResult = ''; # hashed result, duh
|
||||
$hResult{'sd-status'} = getSubdomainStatus();
|
||||
$hResult{'sd-notify'} = getNotifyStatus();
|
||||
Immunix::Ycp::ycpReturnHashAsMap( %hResult );
|
||||
$donereturn = 1;
|
||||
} elsif ( $argument eq 'sd-status') {
|
||||
$result = getSubdomainStatus();
|
||||
} elsif ( $argument eq 'sd-notify') {
|
||||
$result = getNotifyStatus();
|
||||
} elsif ( $argument eq 'sd-notify-settings') {
|
||||
$result = getNotifySettings();
|
||||
Immunix::Ycp::ycpReturn($result);
|
||||
$donereturn = 1;
|
||||
}
|
||||
|
||||
Immunix::Ycp::ycpReturnSkalarAsString( $result ) if ( ! $donereturn );
|
||||
|
||||
} else {
|
||||
|
||||
my $ycpCmd = ycpGetCommand() || "";
|
||||
my $ycpArg = ycpGetArgType() || "";
|
||||
$result = "Unknown instruction $ycpCmd or argument: $ycpArg\n";
|
||||
Immunix::Ycp::ycpReturnSkalarAsString( $result );
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
|
||||
|
140
management/yastui/src/agents/ag_subdomain_profiles
Executable file
|
@ -0,0 +1,140 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
|
||||
#####################################################################
|
||||
#
|
||||
# ag_subdomain_profiles - Immunix SCR agent for the
|
||||
# management of SubDomain profiles
|
||||
#
|
||||
#
|
||||
#####################################################################
|
||||
|
||||
use strict;
|
||||
use Immunix::SubDomain;
|
||||
use Immunix::Ycp;
|
||||
|
||||
################
|
||||
# Subroutines
|
||||
################
|
||||
|
||||
{
|
||||
|
||||
sub newprofile {
|
||||
my $filename = shift;
|
||||
system("/usr/sbin/autodep $filename > /dev/null 2>&1");
|
||||
system("/usr/sbin/enforce $filename > /dev/null 2>&1");
|
||||
return;
|
||||
}
|
||||
|
||||
# ###############################################################################
|
||||
#
|
||||
# YCP <-> SCR Commands:
|
||||
#
|
||||
# Command Path Argument Returns
|
||||
# ------- ---- -------- --------
|
||||
#
|
||||
# Read all hash containing all profiles
|
||||
#
|
||||
# Read .new pathtoprogram true/false (creates new profile)
|
||||
#
|
||||
# Write hash { true/false
|
||||
# PROFILE_NAME =>
|
||||
# pathtoprogram,
|
||||
# PROFILE_HASH =>
|
||||
# <hash containing the
|
||||
# profile defs>
|
||||
# }
|
||||
#
|
||||
# Write .delete pathtoprogram true/fale (deletes profile)
|
||||
#
|
||||
# Write .reload - true (reloads profiles)
|
||||
#
|
||||
#
|
||||
################################################################################
|
||||
|
||||
|
||||
while ( <STDIN> ) {
|
||||
|
||||
my ($command, $path, $argument) = Immunix::Ycp::ParseCommand ($_);
|
||||
$argument = "NONE" if ( ! $argument );
|
||||
Immunix::Ycp::y2milestone ("DOM command: $command, path: $path, argument: $argument");
|
||||
|
||||
my $result = undef;
|
||||
if ( $command && $path && $argument ) {
|
||||
if ( $command eq "Read" and $argument eq "all") {
|
||||
$UI_Mode = "yast";
|
||||
Immunix::SubDomain::readprofiles();
|
||||
Immunix::Ycp::Return( \%sd );
|
||||
} elsif ( $command eq "Read" and $path eq ".new" ) {
|
||||
my $pfname = getprofilefilename($argument);
|
||||
if ( -e $pfname ) {
|
||||
Immunix::Ycp::Return("false");
|
||||
} else {
|
||||
newprofile( $argument );
|
||||
Immunix::Ycp::Return( "true" );
|
||||
}
|
||||
} elsif ( $command eq "Read" ) {
|
||||
my $pfname = getprofilefilename($argument);
|
||||
if ( -e $pfname ) {
|
||||
$UI_Mode = "yast";
|
||||
Immunix::SubDomain::readprofiles();
|
||||
Immunix::Ycp::Return( $sd{$argument} );
|
||||
} else {
|
||||
Immunix::Ycp::Return( "false" );
|
||||
}
|
||||
} elsif ( $command eq "Read") {
|
||||
$UI_Mode = "yast";
|
||||
Immunix::SubDomain::readprofile("$profiledir/$argument");
|
||||
Immunix::Ycp::Return( \%sd );
|
||||
} elsif ( $command eq "Write" and $path eq ".delete") {
|
||||
if ( $argument ne "" ) {
|
||||
my $profilefile = getprofilefilename( $argument );
|
||||
if ( -e $profilefile ) {
|
||||
unlink( $profilefile );
|
||||
}
|
||||
Immunix::Ycp::Return( "true" );
|
||||
} else {
|
||||
Immunix::Ycp::Return( "false" );
|
||||
}
|
||||
} elsif ( $command eq "Write" and $path eq ".reload") {
|
||||
$result = system("/sbin/rcsubdomain reload > /dev/null 2>&1");
|
||||
Immunix::Ycp::Return( "true" );
|
||||
} elsif ( $command eq "Write") {
|
||||
if ( (ref($argument) eq "HASH") ) {
|
||||
my $profilename = "";
|
||||
$profilename = $$argument{"PROFILE_NAME"};
|
||||
my $ref = $$argument{"PROFILE_HASH"};
|
||||
my %profiles = ();
|
||||
$profiles{$profilename} = $ref;
|
||||
if ( (ref($ref) eq "HASH") ) {
|
||||
%sd = %profiles;
|
||||
$UI_Mode = "yast";
|
||||
$result = Immunix::SubDomain::writeprofile($profilename);
|
||||
} else {
|
||||
Immunix::Ycp::Return( "false" );
|
||||
}
|
||||
Immunix::Ycp::Return( "true" );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
my $ycpCmd = ycpGetCommand() || "";
|
||||
my $ycpArg = ycpGetArgType() || "";
|
||||
$result = "Unknown instruction $ycpCmd or argument: $ycpArg\n";
|
||||
Immunix::Ycp::Return( $result );
|
||||
}
|
||||
}
|
||||
}
|
||||
exit 0;
|
||||
|
||||
|
31
management/yastui/src/apparmor/reports.conf
Normal file
|
@ -0,0 +1,31 @@
|
|||
<apparmor>
|
||||
<report>
|
||||
<name>Executive.Security.Summary</name>
|
||||
<exportpath>/var/log/apparmor/reports-archived</exportpath>
|
||||
<exporttype csv="0" html="0" />
|
||||
<email addr1="" addr2="" addr3="" />
|
||||
<time>1104566401</time>
|
||||
</report>
|
||||
<report>
|
||||
<name>Applications.Audit</name>
|
||||
<exportpath>/var/log/apparmor/reports-archived</exportpath>
|
||||
<exporttype csv="0" html="0"/>
|
||||
<email addr1="" addr2="" addr3="" />
|
||||
<time>1104566401</time>
|
||||
</report>
|
||||
<report>
|
||||
<name>Security.Incident.Report</name>
|
||||
<exportpath>/var/log/apparmor/reports-archived</exportpath>
|
||||
<exporttype csv="0" html="0" />
|
||||
<prog></prog>
|
||||
<profile></profile>
|
||||
<pid></pid>
|
||||
<resource></resource>
|
||||
<severity></severity>
|
||||
<sdmode>R</sdmode>
|
||||
<mode></mode>
|
||||
<email addr1="" addr2="" addr3="" />
|
||||
<time>1104566401</time>
|
||||
</report>
|
||||
</apparmor>
|
||||
|
3
management/yastui/src/apparmor/reports.crontab
Normal file
|
@ -0,0 +1,3 @@
|
|||
59 23 * * * /usr/bin/reportgen.pl "Executive.Security.Summary"
|
||||
59 23 * * * /usr/bin/reportgen.pl "Applications.Audit"
|
||||
59 23 * * * /usr/bin/reportgen.pl "Security.Incident.Report"
|
629
management/yastui/src/bin/reportgen.pl
Executable file
|
@ -0,0 +1,629 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
################################################################################
|
||||
# /usr/bin/reportgen.pl
|
||||
#
|
||||
# - Calls Immunix::Reports.pm to write AppArmor events to a specified logfile
|
||||
# - Expected to be executed by a cron job.
|
||||
#
|
||||
# Requires:
|
||||
# /usr/lib/perl5/site_perl/Immunix::Reports.pm
|
||||
#
|
||||
# Input (Optional):
|
||||
# -Report Name
|
||||
# -Program Name 'progName'
|
||||
# -Profile Name 'profile'
|
||||
# -PID 'pid'
|
||||
# -Severity 'sevLevel'
|
||||
# -Denied Resources 'denyRes'
|
||||
# -SD Mode 'sdmode'
|
||||
# -Mode 'mode'
|
||||
#
|
||||
################################################################################
|
||||
use strict;
|
||||
use Immunix::Reports;
|
||||
use POSIX;
|
||||
use Locale::gettext;
|
||||
|
||||
setlocale(LC_MESSAGES, "");
|
||||
textdomain("yast2-apparmor");
|
||||
|
||||
# Sloppy Global
|
||||
my $headerFile = "/var/log/apparmor/reports/reportgen.header";
|
||||
|
||||
# Routines
|
||||
################################################################################
|
||||
sub logMessage {
|
||||
|
||||
my ($msg,$date) = @_;
|
||||
|
||||
if (! $date) {
|
||||
$date = localtime;
|
||||
}
|
||||
|
||||
my $msgLog = '/var/log/apparmor/cron-reports.log';
|
||||
|
||||
if (open (MLOG, ">>$msgLog") ) {
|
||||
print MLOG "$date - reportgen.pl: $msg\n";
|
||||
close MLOG;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub makeHeader {
|
||||
|
||||
my ($repType,$repConf,$filts) = @_; # Filters & Time are only for SIR
|
||||
|
||||
my $header = undef;
|
||||
my $date = localtime;
|
||||
my $start = localtime($repConf->{'startTime'});
|
||||
|
||||
if ( $repType eq 'ess' ) {
|
||||
|
||||
# Write ESS Header in csv format
|
||||
$header->{'csv'} = gettext("# Executive Security Summary - Generated by AppArmor\n");
|
||||
$header->{'csv'} .= sprintf(gettext("# Period: %s to %s\n\n"), $start,$date);
|
||||
|
||||
# Write ESS Header in html format
|
||||
$header->{'html'} = "<table border='1' cellpadding='2'>\n";
|
||||
$header->{'html'} .= gettext("<tr><th colspan='6'>Executive Security Summary - Generated by AppArmor</th></tr>");
|
||||
$header->{'html'} .= sprintf(gettext("<tr><th colspan='6'>Period: %s to %s</th></tr>\n"), $start, $date);
|
||||
|
||||
} elsif ( $repType eq 'aud' ) {
|
||||
|
||||
# Write AUD Header in csv format
|
||||
$header->{'csv'} = gettext("# Application Audit Report - Generated by AppArmor\n");
|
||||
$header->{'csv'} .= sprintf(gettext("# Date Run: %s\n\n"), $date);
|
||||
|
||||
# Write AUD Header in html format
|
||||
$header->{'html'} = gettext("<table border='1' cellpadding='2'><tr><th colspan='7'>Applications Audit Report - Generated by AppArmor</th></tr>\n");
|
||||
#$header->{'html'} .= sprintf(gettext("<tr><th colspan='7'>Date Run: %s</th></tr>\n"), $date);
|
||||
|
||||
} else {
|
||||
|
||||
# Write SIR Header in csv format
|
||||
$header->{'csv'} = gettext("# Security Incident Report - Generated by AppArmor\n");
|
||||
$header->{'csv'} .= sprintf(gettext("# Period: %s - %s\n"), $start, $date);
|
||||
|
||||
my $count = 0;
|
||||
|
||||
if ( $filts ) {
|
||||
# We don't want startdate/enddate to be listed as filters
|
||||
$count = keys(%$filts);
|
||||
if ($filts->{'startdate'}) {
|
||||
$filts->{'startdate'} = localtime($filts->{'startdate'});
|
||||
$count--;
|
||||
}
|
||||
if ($filts->{'enddate'}) {
|
||||
$filts->{'enddate'} = localtime($filts->{'enddate'});
|
||||
$count--;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $count > 0 ) {
|
||||
$header->{'csv'} .= gettext("# The following filters were used for report generation:\n");
|
||||
for (sort keys(%$filts)) {
|
||||
unless ( $filts->{'startdate'} || $filts->{'enddate'} ) {
|
||||
#$header->{'csv'} .= "# Filter: $_, Value: $filts->{$_}\n\n";
|
||||
$header->{'csv'} .= sprintf(gettext("# Filter: %s, Value: %s\n\n"), $_, $filts->{$_});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$header->{'csv'} .= gettext("# No filters were used for report generation:\n\n\n");
|
||||
}
|
||||
|
||||
#if ( $count > 0 ) {
|
||||
# print SIR gettext("# The following filters were used for report generation:\n");
|
||||
# for (sort keys(%$filts)) {
|
||||
##print SIR "# Filter: $_, Value: $filts->{$_}\n\n";
|
||||
# my $entry = sprintf(gettext("# Filter: %s, Value: %s\n\n"), $_, $filts->{$_});
|
||||
# print SIR "$entry";
|
||||
# }
|
||||
#} else {
|
||||
# print SIR "# No filters were used for report generation:\n\n\n";
|
||||
#}
|
||||
|
||||
# Write SIR Header in html format
|
||||
$header->{'html'} = gettext("<h3>Security Incident Report - Generated by AppArmor</h3>\n");
|
||||
$header->{'html'} .= sprintf(gettext("<h4>Period: %s - %s</h4>\n"), $start, $date);
|
||||
|
||||
if ( $count > 0 ) {
|
||||
|
||||
$header->{'html'} .= gettext("<h4>The following filters were used for report generation:</h4>");
|
||||
|
||||
for (sort keys(%$filts)) {
|
||||
#$header->{'html'} .= "<p>Filter: $_, Value: $filts->{$_}</p>";
|
||||
$header->{'html'} .= sprintf(gettext("<p>Filter: %s, Value: %s</p>"), $_, $filts->{$_});
|
||||
}
|
||||
|
||||
} else {
|
||||
$header->{'html'} .= gettext("<h4>No filters were used for report generation.</h4>");
|
||||
}
|
||||
|
||||
$header->{'html'} .= "<hr>\n";
|
||||
|
||||
}
|
||||
|
||||
my $mailHeader = $header->{'csv'};
|
||||
$mailHeader =~ s/^#\s*//;
|
||||
|
||||
if ( open (HDR, ">$headerFile") ) {
|
||||
print HDR "$mailHeader";
|
||||
close HDR;
|
||||
}
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
# Sets name of new report file to generate
|
||||
sub getRepFileName {
|
||||
|
||||
my ($hashName,$dir,$repConf) = @_;
|
||||
my @dirList = ();
|
||||
|
||||
my $plainName = $hashName->{'base'};
|
||||
|
||||
# Append date info to help id reports
|
||||
my ($sec,$min,$hour,$mday,$month,$year,@junk) = localtime;
|
||||
|
||||
$year += 1900;
|
||||
$month += 1;
|
||||
|
||||
$month = sprintf("%02d", $month);
|
||||
$mday = sprintf("%02d", $mday);
|
||||
$hour = sprintf("%02d", $hour);
|
||||
$min = sprintf("%02d", $min);
|
||||
$sec = sprintf("%02d", $sec);
|
||||
$mday = sprintf("%02d", $mday);
|
||||
|
||||
my $suffix = "-$year-$month-$mday\_$hour.$min.$sec";
|
||||
$plainName = $plainName . $suffix;
|
||||
my $qtName = "\"$plainName\"";
|
||||
|
||||
if (opendir (DIR, $dir)) {
|
||||
@dirList = grep(/$qtName/, readdir(DIR) );
|
||||
close DIR;
|
||||
}
|
||||
my $numReps = scalar(@dirList) + 1;
|
||||
$numReps = sprintf("%03d", $numReps);
|
||||
my $newName = undef;
|
||||
|
||||
# Prefix all names w/ .csv -- we'll change to .html later if required
|
||||
$newName = "$dir/$plainName.$numReps.csv";
|
||||
|
||||
return $newName;
|
||||
}
|
||||
|
||||
sub getRepConf {
|
||||
|
||||
my $repName = shift;
|
||||
|
||||
my $repConf = '/etc/apparmor/reports.conf';
|
||||
my $tmpConf = '/var/log/apparmor/reports/reports.conf';
|
||||
my $config = undef;
|
||||
my @mailList = ();
|
||||
my %filts = (); # Report 'record' filters
|
||||
my $rep = Immunix::Reports::getXmlReport($repName);
|
||||
|
||||
if ( scalar(keys(%$rep)) < 2 ) {
|
||||
logMessage(sprintf(gettext("Fatal Error: Couldn't get report configuration information %s. Exiting."), $repConf));
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# remove default filters
|
||||
if ( $rep->{'prog'} && ( $rep->{'prog'} eq '-' || $rep->{'prog'} eq 'All' ) ) {
|
||||
delete $rep->{'prog'};
|
||||
} else {
|
||||
$filts{'prog'} = $rep->{'prog'};
|
||||
}
|
||||
|
||||
if ( $rep->{'profile'} && ( $rep->{'profile'} eq '-' || $rep->{'profile'} eq 'All' ) ) {
|
||||
delete $rep->{'profile'};
|
||||
} else {
|
||||
$filts{'profile'} = $rep->{'profile'};
|
||||
}
|
||||
|
||||
if ( $rep->{'pid'} && ( $rep->{'pid'} eq '-' || $rep->{'pid'} eq 'All' ) ) {
|
||||
delete $rep->{'pid'};
|
||||
} else {
|
||||
$filts{'pid'} = $rep->{'pid'};
|
||||
}
|
||||
|
||||
if ( $rep->{'resource'} && ( $rep->{'resource'} eq '-' || $rep->{'resource'} eq 'All' ) ) {
|
||||
delete $rep->{'resource'};
|
||||
} else {
|
||||
$filts{'resource'} = $rep->{'resource'};
|
||||
}
|
||||
|
||||
if ( $rep->{'severity'} && ( $rep->{'severity'} eq '-' || $rep->{'severity'} eq 'All' ) ) {
|
||||
delete $rep->{'severity'};
|
||||
} else {
|
||||
$filts{'severity'} = $rep->{'severity'};
|
||||
}
|
||||
|
||||
if ( $rep->{'sdmode'} && ( $rep->{'sdmode'} eq '-' || $rep->{'sdmode'} eq 'All' ) ) {
|
||||
delete $rep->{'sdmode'};
|
||||
} else {
|
||||
$filts{'sdmode'} = $rep->{'sdmode'};
|
||||
}
|
||||
|
||||
if ( $rep->{'mode'} && ( $rep->{'mode'} eq '-' || $rep->{'mode'} eq 'All' ) ) {
|
||||
delete $rep->{'mode'};
|
||||
} else {
|
||||
$filts{'mode'} = $rep->{'mode'};
|
||||
}
|
||||
|
||||
# Mail Type - csv, html, or both
|
||||
if ( $rep->{'csv'} eq '1' && $rep->{'html'} eq '1' ) {
|
||||
$rep->{'mailType'} = 'both';
|
||||
} elsif ( $rep->{'csv'} eq '1' && $rep->{'html'} eq '0' ) {
|
||||
$rep->{'mailType'} = 'csv';
|
||||
} elsif ( $rep->{'csv'} eq '0' && $rep->{'html'} eq '1' ) {
|
||||
$rep->{'mailType'} = 'html';
|
||||
} else {
|
||||
$rep->{'mailType'} = 'none';
|
||||
}
|
||||
|
||||
# Mail Address List
|
||||
if ( $rep->{'addr1'} ) { push(@mailList,$rep->{'addr1'}); }
|
||||
if ( $rep->{'addr2'} ) { push(@mailList,$rep->{'addr2'}); }
|
||||
if ( $rep->{'addr3'} ) { push(@mailList,$rep->{'addr3'}); }
|
||||
|
||||
|
||||
$rep->{'startTime'} = $rep->{'time'};
|
||||
$rep->{'endTime'} = time;
|
||||
$rep->{'filters'} = %filts;
|
||||
$rep->{'mailList'} = \@mailList;
|
||||
|
||||
return $rep;
|
||||
|
||||
}
|
||||
|
||||
# Updates last-run time sig. in reports.conf
|
||||
sub updateConf {
|
||||
|
||||
my ($repName, $repConf) = @_;
|
||||
my $time = $repConf->{'endTime'};
|
||||
|
||||
if (! $time) { $time = time; }
|
||||
|
||||
#if ( ref($repName) ) { $repName = $repName->{'base'}; }
|
||||
|
||||
my $repCfFile = '/etc/apparmor/reports.conf';
|
||||
my $tmpConf = '/var/log/apparmor/reports/reports.conf';
|
||||
|
||||
if ( open(OCF, "<$repCfFile") ) {
|
||||
|
||||
if ( open(TCF, ">$tmpConf") ) {
|
||||
|
||||
my $nameFlag = 0;
|
||||
|
||||
while(<OCF>) {
|
||||
|
||||
chomp;
|
||||
|
||||
if ( /\<name\>/ ) {
|
||||
#my $name = (split(/\"/, $_))[1];
|
||||
/\<name\>(.+)\<\/name\>/;
|
||||
my $name = $1;
|
||||
if ( $name eq $repName->{'base'} ) {
|
||||
$nameFlag = 1;
|
||||
}
|
||||
} elsif ( $nameFlag == 1 ) {
|
||||
if ( /\<time\>/ ) {
|
||||
$_ = "\t<time>$time</time>";
|
||||
$nameFlag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
print TCF "$_\n";
|
||||
}
|
||||
|
||||
close TCF;
|
||||
|
||||
} else {
|
||||
#logMessage("Error: Couldn't open (tmp) $tmpConf. ESS report execution not tracked.");
|
||||
logMessage(sprintf(gettext("Error: Couldn't open (tmp) %s. ESS report execution not tracked."), $tmpConf));
|
||||
}
|
||||
|
||||
close OCF;
|
||||
} else {
|
||||
logMessage(sprintf(gettext("Error: Couldn't open %s. ESS report execution not tracked."), $repCfFile));
|
||||
}
|
||||
|
||||
if ( -e $repCfFile && -e $tmpConf ) {
|
||||
Immunix::Reports::updateFiles($repCfFile,$tmpConf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
sub sendMail {
|
||||
|
||||
my ($repName,$repFile,$repConf) = @_;
|
||||
my $repCfFile = '/etc/apparmor/reports.conf';
|
||||
|
||||
if (! $repName || ! $repFile) {
|
||||
logMessage(gettext("Error: Necessary input missing. Unable to generate report and send mail."));
|
||||
return 1;
|
||||
}
|
||||
|
||||
my $baseName = $repName->{'base'};
|
||||
|
||||
my $host = `hostname -f`;
|
||||
chomp($host);
|
||||
|
||||
my $toMail = $repConf->{'mailList'};
|
||||
my $rec = undef;
|
||||
|
||||
if ( @$toMail > 0 ) {
|
||||
for (@$toMail) {
|
||||
if ( $repConf->{'mailType'} ) {
|
||||
if ( $repConf->{'mailType'} eq 'csv' ) {
|
||||
#`/usr/bin/mail $_ -s $baseName -r "AppArmor_Reporting\@$host" -a $repFile < /dev/null`;
|
||||
`/usr/bin/mail $_ -s $baseName -r "AppArmor_Reporting\@$host" -a $repFile < $headerFile`;
|
||||
} elsif ( $repConf->{'mailType'} eq 'html' ) {
|
||||
$repFile =~ s/csv/html/;
|
||||
#`/usr/bin/mail $_ -s $baseName -r "AppArmor_Reporting\@$host" -a $repFile < /dev/null`;
|
||||
`/usr/bin/mail $_ -s $baseName -r "AppArmor_Reporting\@$host" -a $repFile < $headerFile`;
|
||||
} elsif ( $repConf->{'mailType'} eq 'both' ) {
|
||||
my $rep2 = $repFile;
|
||||
$rep2 =~ s/csv/html/;
|
||||
#`/usr/bin/mail $_ -s $baseName -r "AppArmor_Reporting\@$host" -a $repFile -a $rep2 < /dev/null`;
|
||||
`/usr/bin/mail $_ -s $baseName -r "AppArmor_Reporting\@$host" -a $repFile -a $rep2 < $headerFile`;
|
||||
}
|
||||
} else {
|
||||
`/usr/bin/mail $_ -s $repName -r "AppArmor_Reporting\@$host" -a $repFile < $headerFile`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub runEss {
|
||||
|
||||
my ($repName,$repConf) = @_;
|
||||
#my ($repName,$date,$lastRun) = @_;
|
||||
|
||||
my $ref = ();
|
||||
# getSevStats from ag_reports_ess
|
||||
my $db = Immunix::Reports::getEssStats($ref);
|
||||
|
||||
my $header = makeHeader('ess',$repConf);
|
||||
|
||||
if ( $repConf->{'startTime'} && $repConf->{'startTime'} > 0 ) {
|
||||
$ref->{'startdate'} = $repConf->{'startTime'};
|
||||
} else {
|
||||
$ref->{'startdate'} = 1104566401;
|
||||
}
|
||||
|
||||
# CSV
|
||||
if ( $repConf->{'mailType'} eq 'csv' || $repConf->{'mailType'} eq 'both' ) {
|
||||
if ( open(ESS, ">$repName") ) {
|
||||
|
||||
print ESS "$header->{'csv'}";
|
||||
|
||||
for (@$db) {
|
||||
$_->{'startdate'} = Immunix::Reports::getDate("$repConf->{'startTime'}");
|
||||
$_->{'enddate'} = Immunix::Reports::getDate("$repConf->{'endTime'}");
|
||||
print ESS "$_->{'host'},$_->{'startdate'},$_->{'enddate'},";
|
||||
print ESS "$_->{'sevHi'},$_->{'sevMean'},$_->{'numRejects'},$_->{'numEvents'}\n";
|
||||
}
|
||||
|
||||
close ESS;
|
||||
|
||||
} else {
|
||||
logMessage(sprintf(gettext("Error: Couldn't open %s. No ESS csv report generated."), $repName));
|
||||
}
|
||||
}
|
||||
|
||||
# HTML
|
||||
if ( $repConf->{'mailType'} eq 'html' || $repConf->{'mailType'} eq 'both' ) {
|
||||
$repName =~ s/csv/html/;
|
||||
if ( open(ESS, ">$repName") ) {
|
||||
|
||||
print ESS "<html><body bgcolor='fffeec'><font face='Helvetica,Arial,Sans-Serif'>\n";
|
||||
print ESS "$header->{'html'}";
|
||||
print ESS gettext("<tr bgcolor='edefff'><td>Hostname</td><td>Start Date</td><td>End Date</td>");
|
||||
print ESS gettext("<td>Highest Severity</td><td>Mean Severity</td><td>Number of REJECTs</td>");
|
||||
print ESS gettext("<td>Number of Events</td></tr>\n");
|
||||
|
||||
for (@$db) {
|
||||
$_->{'startdate'} = Immunix::Reports::getDate("$repConf->{'startTime'}");
|
||||
$_->{'enddate'} = Immunix::Reports::getDate("$repConf->{'endTime'}");
|
||||
print ESS "<tr><td>$_->{'host'}</td><td>$_->{'startdate'}</td><td>$_->{'enddate'}</td>";
|
||||
print ESS "<td>$_->{'sevHi'}</td><td>$_->{'sevMean'}</td><td>$_->{'numRejects'}</td>";
|
||||
print ESS "<td>$_->{'numEvents'}</td></tr>\n";
|
||||
}
|
||||
|
||||
print ESS "</table><br></body></html>";
|
||||
close ESS;
|
||||
|
||||
} else {
|
||||
logMessage(sprintf(gettext("Error: Couldn't open %s. No ESS html report generated."), $repName));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub runAud {
|
||||
|
||||
my ($repName,$repConf) = @_;
|
||||
my $header = makeHeader('aud',$repConf);
|
||||
|
||||
# CSV
|
||||
if ( $repConf->{'mailType'} eq 'csv' || $repConf->{'mailType'} eq 'both' ) {
|
||||
if ( open(AUD, ">$repName") ) {
|
||||
|
||||
my $db = Immunix::Reports::getCfInfo();
|
||||
|
||||
print AUD "$header->{'csv'}";
|
||||
|
||||
for (@$db) {
|
||||
print AUD "$_->{'host'},$_->{'date'},$_->{'prog'}, $_->{'prof'}, $_->{'pid'},";
|
||||
if ( $_->{'state'} eq 'confined' ) {
|
||||
print AUD "$_->{'state'},$_->{'type'}\n";
|
||||
} else {
|
||||
print AUD "$_->{'state'}, - \n";
|
||||
}
|
||||
}
|
||||
|
||||
close AUD;
|
||||
|
||||
} else {
|
||||
logMessage(sprintf(gettext("Error: Couldn't open %s. No AUD report generated."), $repName));
|
||||
}
|
||||
}
|
||||
|
||||
# HTML
|
||||
if ( $repConf->{'mailType'} eq 'html' || $repConf->{'mailType'} eq 'both' ) {
|
||||
|
||||
$repName =~ s/csv/html/;
|
||||
if ( open(AUD, ">>$repName") ) {
|
||||
|
||||
my $db = Immunix::Reports::getCfInfo();
|
||||
|
||||
print AUD "<html><body bgcolor='fffeec'><font face='Helvetica,Arial,Sans-Serif'>\n";
|
||||
print AUD gettext("<h3>Applications Audit Report - Generated by AppArmor</h3>\n");
|
||||
print AUD "$header->{'html'}";
|
||||
print AUD gettext("<tr bgcolor='edefff'><td>Hostname</td><td>Date</td><td>Application</td>");
|
||||
print AUD gettext("<td>Profile</td><td>PID</td><td>State</td><td>AppArmor Profile</td></tr>\n");
|
||||
|
||||
for (@$db) {
|
||||
print AUD "<tr><td>$_->{'host'}</td><td>$_->{'date'}</td><td>$_->{'prog'}</td><td>$_->{'prof'}</td>";
|
||||
if ( $_->{'state'} eq 'confined' ) {
|
||||
print AUD "<td>$_->{'pid'}</td><td>$_->{'state'}</td><td>$_->{'type'}</td></tr>\n";
|
||||
} else {
|
||||
print AUD "<td>$_->{'pid'}</td><td>$_->{'state'}</td><td align='center'> - </td></tr>\n";
|
||||
}
|
||||
}
|
||||
|
||||
print AUD "<br></table></body></html>\n";
|
||||
|
||||
close AUD;
|
||||
|
||||
} else {
|
||||
logMessage(sprintf(gettext("Error: Couldn't open %s. No AUD report generated."), $repName));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub runSir {
|
||||
|
||||
my ($repName,$repFile,$repConf) = @_;
|
||||
|
||||
my $filts = Immunix::Reports::setFormFilters($repConf);
|
||||
#my $filts = $repConf->{'filters'};
|
||||
$filts = Immunix::Reports::rewriteFilters($filts);
|
||||
|
||||
my $start = '1104566401'; # default start, Jan 1, 2005
|
||||
|
||||
if ( $repConf->{'startTime'} && $repConf->{'startTime'} > 0 ) {
|
||||
$start = $repConf->{'startTime'};
|
||||
}
|
||||
|
||||
my $db = Immunix::Reports::grabEvents($filts,$start);
|
||||
|
||||
if ($repConf->{'start'} && $repConf->{'start'} > $start ) {
|
||||
$start = localtime($repConf->{'startTime'});
|
||||
}
|
||||
|
||||
my $end = localtime($repConf->{'endTime'});
|
||||
|
||||
my $header = makeHeader('sir',$repConf,$filts);
|
||||
|
||||
# CSV
|
||||
if ( $repConf->{'mailType'} =~ /csv/ || $repConf->{'mailType'} =~ /both/ ) {
|
||||
|
||||
if ( open(SIR, ">$repFile") ) {
|
||||
|
||||
#my $ref = getSirFilters($repName);
|
||||
|
||||
# Write Header
|
||||
print SIR "$header->{'csv'}";
|
||||
|
||||
#Immunix::Reports::exportFormattedText($repName,$repFile,$db); # Replaced stuff below
|
||||
|
||||
for (@$db) {
|
||||
print SIR "$_->{'host'},$_->{'date'},$_->{'prog'},$_->{'profile'},$_->{'pid'},";
|
||||
print SIR "$_->{'severity'},$_->{'mode'},$_->{'resource'},$_->{'sdmode'}\n";
|
||||
}
|
||||
|
||||
close SIR;
|
||||
|
||||
} else {
|
||||
logMessage(sprintf(gettext("Error: Couldn't open %s. No SIR report generated."), $repFile));
|
||||
}
|
||||
}
|
||||
|
||||
# HTML
|
||||
if ( $repConf->{'mailType'} =~ /html/ || $repConf->{'mailType'} =~ /both/ ) {
|
||||
#my $repName = $repConf->{'name'};
|
||||
#$repName =~ s/csv/html/;
|
||||
$repFile =~ s/csv/html/;
|
||||
|
||||
#Immunix::Reports::exportLog($repName,$repFile,$db);
|
||||
Immunix::Reports::exportLog($repFile,$db,$header->{'html'});
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Main
|
||||
################################################################################
|
||||
if (! $ARGV[0]) {
|
||||
logMessage(gettext("Error: No arguments passed--Unable to execute reports. Exiting."));
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $args = undef;
|
||||
my @dirList = ();
|
||||
#my $date = localtime;
|
||||
my $dir = '/var/log/apparmor/reports-archived';
|
||||
my $repName = undef;
|
||||
|
||||
$repName->{'base'} = $ARGV[0]; # Report Name
|
||||
$repName->{'quoted'} = "\"$repName->{'base'}\""; # Quoted Report Name
|
||||
|
||||
logMessage(sprintf(gettext("Executing Scheduled Report: %s"), $repName->{'base'}));
|
||||
|
||||
my $repConf = getRepConf($repName);
|
||||
|
||||
if ( $repConf->{'exportpath'} && -d $repConf->{'exportpath'} ) {
|
||||
$dir = $repConf->{'exportpath'};
|
||||
}
|
||||
|
||||
my $repFile = getRepFileName($repName,$dir,$repConf);
|
||||
|
||||
if ($repName->{'base'} =~ /Executive.Security.Summary/) {
|
||||
runEss($repFile,$repConf);
|
||||
} elsif ($repName->{'base'} =~ /Applications.Audit/) {
|
||||
runAud($repFile,$repConf);
|
||||
} else {
|
||||
# Security Incident Report
|
||||
runSir($repName,$repFile,$repConf);
|
||||
}
|
||||
|
||||
if ( ! -e $headerFile ) { $headerFile = '/dev/null'; }
|
||||
|
||||
sendMail($repName,$repFile,$repConf);
|
||||
updateConf($repName,$repConf);
|
||||
|
||||
exit 0;
|
||||
|
411
management/yastui/src/clients/GenProf.ycp
Normal file
|
@ -0,0 +1,411 @@
|
|||
/* ------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2002-2006 Novell/SUSE
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License published by the Free Software Foundation.
|
||||
*
|
||||
------------------------------------------------------------------*/
|
||||
{
|
||||
import "Label";
|
||||
import "Wizard";
|
||||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
boolean done = false;
|
||||
string type = "";
|
||||
string status = "";
|
||||
|
||||
map CMDS = $[ ];
|
||||
CMDS["CMD_ALLOW"] = _("&Allow");
|
||||
CMDS["CMD_DENY"] = _("&Deny");
|
||||
CMDS["CMD_ABORT"] = _("Abo(r)t");
|
||||
CMDS["CMD_FINISHED"] = _("&Finish");
|
||||
CMDS["CMD_INHERIT"] = _("&Inherit");
|
||||
CMDS["CMD_PROFILE"] = _("&Profile");
|
||||
CMDS["CMD_UNCONFINED"] = _("&Unconfined");
|
||||
CMDS["CMD_NEW"] = _("&Edit");
|
||||
CMDS["CMD_GLOB"] = _("&Glob");
|
||||
CMDS["CMD_GLOBEXT"] = _("Glob w/E&xt");
|
||||
CMDS["CMD_ADDHAT"] = _("&Add Requested Hat");
|
||||
CMDS["CMD_USEDEFAULT"] = _("&Use Default Hat");
|
||||
CMDS["CMD_SCAN"] = _("&Scan system log for AppArmor events");
|
||||
|
||||
if (!installAppArmorPackages()) {
|
||||
return;
|
||||
}
|
||||
// initiate the handshake with the backend agent
|
||||
map agent_data = (map) SCR::Read(.genprof);
|
||||
|
||||
// is the backend just starting up?
|
||||
type = (string) agent_data["type"]:"handshake_error";
|
||||
status = (string) agent_data["status"]:"handshake_error";
|
||||
if((type != "initial_handshake") || (status != "backend_starting")) {
|
||||
Popup::Error(_("Synchronization error between frontend and backend."));
|
||||
done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// tell the backend tht we're just starting also...
|
||||
agent_data["status"] = "frontend_starting";
|
||||
SCR::Write(.genprof, agent_data);
|
||||
|
||||
// open up the initial form window...
|
||||
Wizard::CreateDialog();
|
||||
|
||||
// start our main event
|
||||
repeat {
|
||||
|
||||
agent_data = (map) SCR::Read(.genprof);
|
||||
|
||||
string type = (string) agent_data["type"]:"error";
|
||||
if(type == "initial_handshake") {
|
||||
Popup::Error(_("Synchronization error between frontend and backend."));
|
||||
done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(type == "wizard") {
|
||||
|
||||
string command = "CMD_ABORT";
|
||||
|
||||
string title = agent_data["title"]:_("AppArmor Profile Wizard");
|
||||
string helptext = agent_data["helptext"]:_(" <b>AppArmor Profiling Wizard</b><br>
|
||||
This wizard presents entries generated by the AppArmor access control module. You can generate highly optimized and robust security profiles by using the suggestions made by AppArmor. AppArmor suggests that you allow or deny access to specific resources or define execute permission for entries. These questions that display were logged during the normal application execution test previously performed. <br>
|
||||
The following help text describes the detail of the security profile syntax used by AppArmor. <br><br>At any stage, you may customize the profile entry by changing the suggested response. This overview will assist you in your options. Refer to the Admin Guide for step-by-step instructions.
|
||||
<br><br>
|
||||
<b>Access Modes</b><br>
|
||||
|
||||
File permission access modes consists of combinations of
|
||||
the following six modes:
|
||||
|
||||
<ul> <li>r - read</li>
|
||||
<li>w - write</li>
|
||||
<li>px - discrete profile execute</li>
|
||||
<li>ux - unconfined execute</li>
|
||||
<li>ix - inherit execute</li>
|
||||
<li>l - link</li>
|
||||
</ul>
|
||||
<p>
|
||||
<br> <b>Details for Access Modes</b>
|
||||
<br><br>
|
||||
<b>Read mode</b><br>
|
||||
Allows the program to have read access to the
|
||||
resource. Read access is required for shell scripts
|
||||
and other interpreted content, and determines if an
|
||||
executing process can core dump or be attached to with
|
||||
ptrace(2). (ptrace(2) is used by utilities such as
|
||||
strace(1), ltrace(1), and gdb(1).)
|
||||
<br>
|
||||
<br>
|
||||
<b>Write mode</b><br>
|
||||
Allows the program to have write access to the
|
||||
resource. Files must have this permission if they are
|
||||
to be unlinked (removed.)
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
<b>Unconfined execute mode</b><br>
|
||||
|
||||
Allows the program to execute the resource without any
|
||||
AppArmor profile being applied to the executed
|
||||
resource. Requires listing execute mode as well.
|
||||
Incompatible with Inherit and Discrete Profile execute
|
||||
entries.
|
||||
<br><br>
|
||||
|
||||
This mode is useful when a confined program needs to
|
||||
be able to perform a privileged operation, such as
|
||||
rebooting the machine. By placing the privileged section
|
||||
in another executable and granting unconfined
|
||||
execution rights, it is possible to bypass the mandatory
|
||||
constraints imposed on all confined processes.
|
||||
For more information on what is constrained, see the
|
||||
subdomain(7) man page.
|
||||
<br><br> <b>Discrete Profile execute mode</b><br>
|
||||
This mode requires that a discrete security profile is
|
||||
defined for a resource executed at a AppArmor domain
|
||||
transition. If there is no profile defined then the
|
||||
access will be denied. Incompatible with Inherit and
|
||||
Unconstrained execute entries.
|
||||
<br>
|
||||
<br>
|
||||
<b>Link mode</b><br>
|
||||
Allows the program to be able to create and remove a
|
||||
link with this name (including symlinks). When a link
|
||||
is created, the file that is being linked to MUST have
|
||||
the same access permissions as the link being created
|
||||
(with the exception that the destination does not have
|
||||
to have link access.) Link access is required for
|
||||
unlinking a file.
|
||||
<br>
|
||||
<br>
|
||||
<b>Globbing</b>
|
||||
<br>
|
||||
<br>
|
||||
File resources may be specified with a globbing syntax
|
||||
similar to that used by popular shells, such as csh(1),
|
||||
bash(1), zsh(1).
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<li><b>*</b> can substitute for any number of characters, excepting
|
||||
'/'<li>
|
||||
|
||||
<li><b>**</b> can substitute for any number of characters, including '/'</li>
|
||||
|
||||
|
||||
<li><b>?</b> can substitute for any single character excepting '/'</li>
|
||||
|
||||
<li><b>[abc]</b> will substitute for the single character a, b, or c</li>
|
||||
|
||||
<li><b>[a-c]</b> will substitute for the single character a, b, or c</li>
|
||||
|
||||
<li><b>{ab,cd}</b> will expand to one rule to match ab, one rule to match
|
||||
cd</li>\n
|
||||
</ul>");
|
||||
|
||||
|
||||
list<string> headers = agent_data["headers"]:[];
|
||||
list<string> options = agent_data["options"]:[];
|
||||
list<string> functions = agent_data["functions"]:["CMD_ABORT"];
|
||||
string explanation = agent_data["explanation"]:"";
|
||||
string default_button = agent_data["default"]:"NO_DEFAULT";
|
||||
integer selected = agent_data["selected"]:0;
|
||||
|
||||
integer idx = 0;
|
||||
|
||||
// build up the list of headers
|
||||
term ui_headers = `VBox(`VSpacing(0.5));
|
||||
while(idx < size(headers)) {
|
||||
string field = headers[idx]:"MISSING FIELD";
|
||||
string value = (string) tostring(headers[idx+1]:"MISSING VALUE");
|
||||
ui_headers = add(ui_headers, `Left(`HBox(`Heading(field), `HSpacing(0.5), `HWeight(75, `Label(value)))));
|
||||
idx = idx + 2;
|
||||
}
|
||||
ui_headers = add(ui_headers, `VSpacing(0.5));
|
||||
|
||||
// build up the option list if we have one
|
||||
idx = 0;
|
||||
term ui_options = `VBox(`VSpacing(0.5));
|
||||
foreach (string option, options, ``{
|
||||
ui_options = add(ui_options, `Left(`RadioButton(`id(idx), option)));
|
||||
idx = idx + 1;
|
||||
});
|
||||
ui_options = add(ui_options, `VSpacing(0.5));
|
||||
|
||||
// build up the set of buttons for the different actions we support
|
||||
term ui_functions = `HBox( `HSpacing(`opt(`hstretch), 0.1) );
|
||||
foreach (string function, functions, ``{
|
||||
if((function != "CMD_ABORT") && (function != "CMD_FINISHED")) {
|
||||
string buttontext = CMDS[function]:"MISSING BUTTON TEXT";
|
||||
ui_functions = add(ui_functions, `HCenter(`PushButton(`id(function), buttontext)));
|
||||
}
|
||||
});
|
||||
ui_functions = add(ui_functions, `HSpacing(`opt(`hstretch), 0.1));
|
||||
|
||||
// throw it all together
|
||||
term contents = `VBox(
|
||||
`Top(
|
||||
`VBox(
|
||||
ui_headers,
|
||||
`Label(explanation),
|
||||
`RadioButtonGroup(ui_options),
|
||||
`VSpacing(`opt(`vstretch), 1),
|
||||
ui_functions
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// update the ui to reflect our new form state...
|
||||
Wizard::SetContents(title, contents, helptext, false, true);
|
||||
// fix up the label on the next/finish button
|
||||
Wizard::SetNextButton(`next, Label::FinishButton() );
|
||||
|
||||
// select and enable to correct buttons
|
||||
idx = 0;
|
||||
foreach (string option, options, ``{
|
||||
UI::ChangeWidget (`id(idx), `Value, selected == idx);
|
||||
idx = idx + 1;
|
||||
});
|
||||
|
||||
// set the focus to be the default action, if we have one
|
||||
if(default_button != "NO_DEFAULT") {
|
||||
UI::SetFocus(`id (default_button));
|
||||
}
|
||||
|
||||
// wait for user input
|
||||
any ret = Wizard::UserInput();
|
||||
|
||||
map answers = $[ ];
|
||||
|
||||
// figure out which button they pressed
|
||||
if (ret == `abort) {
|
||||
answers["selection"] = "CMD_ABORT";
|
||||
} else if (ret == `next) {
|
||||
answers["selection"] = "CMD_FINISHED";
|
||||
} else {
|
||||
foreach (string function, functions, ``{
|
||||
if(ret == function) {
|
||||
answers["selection"] = function;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// figure out which option was selected
|
||||
idx = 0;
|
||||
foreach (string option, options, ``{
|
||||
if(UI::QueryWidget(`id(idx), `Value) == true) {
|
||||
answers["selected"] = option;
|
||||
}
|
||||
idx = idx + 1;
|
||||
});
|
||||
|
||||
// tell the backend what they did
|
||||
SCR::Write(.genprof, answers);
|
||||
|
||||
} else if (type == "dialog-yesno") {
|
||||
|
||||
string question = agent_data["question"]:"MISSING QUESTION";
|
||||
string default_ans = agent_data["default"]:"n";
|
||||
|
||||
symbol focus = `focus_no;
|
||||
if(default_ans == "y") {
|
||||
focus = `focus_yes;
|
||||
}
|
||||
|
||||
map answers = $[ ];
|
||||
if(Popup::AnyQuestion(Popup::NoHeadline(), question, _("&Yes"), _("&No"), focus)) {
|
||||
answers["answer"] = "y";
|
||||
} else {
|
||||
answers["answer"] = "n";
|
||||
}
|
||||
|
||||
# write the answers for the last dialog
|
||||
boolean written = SCR::Write(.genprof, answers);
|
||||
|
||||
} else if (type == "dialog-getstring") {
|
||||
|
||||
string label = agent_data["label"]:"MISSING LABEL";
|
||||
string default_value = agent_data["default"]:"MISSING DEFAULT";
|
||||
|
||||
term dialog = `VBox(
|
||||
`TextEntry(`id (`stringfield), label, default_value),
|
||||
`HBox(
|
||||
`HWeight(1, `PushButton(`id(`okay), `opt(`default, `key_F10), _("&Okay"))),
|
||||
`HSpacing(2),
|
||||
`HWeight(1, `PushButton(`id(`cancel), `opt(`key_F9), _("&Cancel")))
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
UI::OpenDialog(dialog);
|
||||
UI::SetFocus(`id(`stringfield));
|
||||
|
||||
any poo = UI::UserInput();
|
||||
|
||||
map answers = $[ ];
|
||||
if(poo == `okay) {
|
||||
answers["string"] = (string) UI::QueryWidget(`id(`stringfield), `Value);
|
||||
} else {
|
||||
answers["string"] = "";
|
||||
}
|
||||
|
||||
UI::CloseDialog();
|
||||
|
||||
# write the answers for the last dialog
|
||||
boolean written = SCR::Write(.genprof, answers);
|
||||
|
||||
} else if (type == "dialog-getfile") {
|
||||
|
||||
string description = agent_data["description"]:"GETFILE: MISSING DESCRIPTION";
|
||||
string file_label = agent_data["file_label"]:"GETFILE: MISSING FILE:LABEL";
|
||||
string okay_label = agent_data["okay_label"]:"GETFILE: MISSING OKAY_LABEL";
|
||||
string cancel_label = agent_data["cancel_label"]:"GETFILE: MISSING CANCEL_LABEL";
|
||||
string browse_desc = agent_data["browse_desc"]:"GETFILE: MISSING BROWSE_DESC";
|
||||
|
||||
term dialog = `VBox(
|
||||
`Top(
|
||||
`VBox(
|
||||
`VSpacing(1),
|
||||
`Left(`Label(description)),
|
||||
`VSpacing(0.5),
|
||||
`Left(`TextEntry(`id(`filename), file_label, "")),
|
||||
`VSpacing(`opt(`vstretch), 0.25)
|
||||
)
|
||||
),
|
||||
`HBox( `HCenter(`PushButton(`id(`browse), _("&Browse")))),
|
||||
`HBox(
|
||||
`HSpacing(`opt(`hstretch), 0.1),
|
||||
`HCenter(`PushButton(`id(`okay), `opt(`default), okay_label)),
|
||||
`HCenter(`PushButton(`id(`cancel), cancel_label)),
|
||||
`HSpacing(`opt(`hstretch), 0.1),
|
||||
`VSpacing(1)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
UI::OpenDialog(dialog);
|
||||
|
||||
map<string,string> answers = $[ ];
|
||||
any poo = false;
|
||||
repeat {
|
||||
UI::SetFocus(`id(`filename));
|
||||
|
||||
poo = UI::UserInput();
|
||||
if(poo == `okay) {
|
||||
answers["answer"] = "okay";
|
||||
answers["filename"] = (string) UI::QueryWidget(`id(`filename), `Value);
|
||||
} else if(poo == `cancel) {
|
||||
answers["answer"] = "cancel";
|
||||
} else if ( poo == `browse ) {
|
||||
string selectfilename = UI::AskForExistingFile( "/", "", browse_desc);
|
||||
UI::ChangeWidget(`id(`filename), `Value, selectfilename);
|
||||
}
|
||||
} until ((poo == `okay) || (poo == `cancel));
|
||||
|
||||
UI::CloseDialog();
|
||||
|
||||
// tell the backend what they picked
|
||||
boolean written = SCR::Write(.genprof, answers);
|
||||
|
||||
} else if (type == "dialog-error") {
|
||||
|
||||
string message = agent_data["message"]:"MISSING QUESTION";
|
||||
|
||||
Popup::Error(message);
|
||||
|
||||
map answers = $[ ];
|
||||
answers["answer"] = "okay";
|
||||
|
||||
// tell the backend that the user has acknowledged the error
|
||||
boolean written = SCR::Write(.genprof, answers);
|
||||
|
||||
} else if (type == "final_shutdown") {
|
||||
done = true;
|
||||
|
||||
map answers = $[ ];
|
||||
answers["type"] = "shutdown_acknowledge";
|
||||
answers["status"] = "shutting_down";
|
||||
|
||||
// tell the backend that we're shutting down also
|
||||
boolean written = SCR::Write(.genprof, answers);
|
||||
|
||||
} else {
|
||||
|
||||
string errortext = "Email support@novell.com: " + type;
|
||||
Popup::Error(errortext);
|
||||
done = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
} until ( done == true);
|
||||
|
||||
Wizard::CloseDialog();
|
||||
|
||||
}
|
408
management/yastui/src/clients/LogProf.ycp
Normal file
|
@ -0,0 +1,408 @@
|
|||
/* ------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2002-2006 Novell/SUSE
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License published by the Free Software Foundation.
|
||||
*
|
||||
------------------------------------------------------------------*/
|
||||
{
|
||||
import "Label";
|
||||
import "Wizard";
|
||||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
boolean done = false;
|
||||
string type = "";
|
||||
string status = "";
|
||||
|
||||
map CMDS = $[ ];
|
||||
CMDS["CMD_ALLOW"] = _("&Allow");
|
||||
CMDS["CMD_DENY"] = _("&Deny");
|
||||
CMDS["CMD_ABORT"] = _("Abo(r)t");
|
||||
CMDS["CMD_FINISHED"] = _("&Finish");
|
||||
CMDS["CMD_INHERIT"] = _("&Inherit");
|
||||
CMDS["CMD_PROFILE"] = _("&Profile");
|
||||
CMDS["CMD_UNCONFINED"] = _("&Unconfined");
|
||||
CMDS["CMD_NEW"] = _("&Edit");
|
||||
CMDS["CMD_GLOB"] = _("&Glob");
|
||||
CMDS["CMD_GLOBEXT"] = _("Glob w/E&xt");
|
||||
CMDS["CMD_ADDHAT"] = _("&Add Requested Hat");
|
||||
CMDS["CMD_USEDEFAULT"] = _("&Use Default Hat");
|
||||
CMDS["CMD_SCAN"] = _("&Scan system log for AppArmor events");
|
||||
|
||||
if (!installAppArmorPackages()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// initiate the handshake with the backend agent
|
||||
map agent_data = (map) SCR::Read(.logprof);
|
||||
|
||||
// is the backend just starting up?
|
||||
type = (string) agent_data["type"]:"handshake_error";
|
||||
status = (string) agent_data["status"]:"handshake_error";
|
||||
if((type != "initial_handshake") || (status != "backend_starting")) {
|
||||
Popup::Error(_("Synchronization error between frontend and backend."));
|
||||
done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// tell the backend tht we're just starting also...
|
||||
agent_data["status"] = "frontend_starting";
|
||||
SCR::Write(.logprof, agent_data);
|
||||
|
||||
// open up the initial form window...
|
||||
Wizard::CreateDialog();
|
||||
|
||||
// start our main event
|
||||
repeat {
|
||||
|
||||
agent_data = (map) SCR::Read(.logprof);
|
||||
|
||||
string type = (string) agent_data["type"]:"error";
|
||||
if(type == "initial_handshake") {
|
||||
Popup::Error(_("Synchronization error between frontend and backend."));
|
||||
done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(type == "wizard") {
|
||||
|
||||
string command = "CMD_ABORT";
|
||||
|
||||
string title = agent_data["title"]:_("AppArmor Profile Wizard");
|
||||
string helptext = agent_data["helptext"]:_(" <b>AppArmor Profiling Wizard</b><br>
|
||||
This wizard presents entries generated by the AppArmor access control module. You can generate highly optimized and robust security profiles by using the suggestions made by AppArmor. AppArmor suggests that you allow or deny access to specific resources or define execute permission for entries. These questions that display were logged during the normal application execution test previously performed. <br>
|
||||
The following help text describes the detail of the security profile syntax used by AppArmor. <br><br>At any stage, you may customize the profile entry by overriding the suggestion. This overview will assist you in your options. Refer to the Admin Guide for step-by-step instructions.
|
||||
<br><br>
|
||||
|
||||
<b>Access Modes</b><br>
|
||||
|
||||
File permission access modes consists of combinations of
|
||||
the following six modes:
|
||||
|
||||
<ul> <li>r - read</li>
|
||||
<li>w - write</li>
|
||||
<li>px - discrete profile execute</li>
|
||||
<li>ux - unconfined execute</li>
|
||||
<li>ix - inherit execute</li>
|
||||
<li>l - link</li>
|
||||
</ul>
|
||||
<p><br>
|
||||
<b>Details for Access Modes</b>
|
||||
<br><br>
|
||||
<b>Read mode</b><br>
|
||||
Allows the program to have read access to the
|
||||
resource. Read access is required for shell scripts
|
||||
and other interpreted content, and determines if an
|
||||
executing process can core dump or be attached to with
|
||||
ptrace(2). (ptrace(2) is used by utilities such as
|
||||
strace(1), ltrace(1), and gdb(1).)
|
||||
<br>
|
||||
<br>
|
||||
<b>Write mode</b><br>
|
||||
Allows the program to have write access to the
|
||||
resource. Files must have this permission if they are
|
||||
to be unlinked (removed.)
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
<b>Unconfined execute mode</b><br>
|
||||
|
||||
Allows the program to execute the resource without any
|
||||
AppArmor profile being applied to the executed
|
||||
resource. Requires listing execute mode as well.
|
||||
Incompatible with Inherit and Discrete Profile execute
|
||||
entries.
|
||||
<br><br>
|
||||
|
||||
This mode is useful when a confined program needs to
|
||||
be able to perform a privileged operation, such as
|
||||
rebooting the machine. By placing the privileged section
|
||||
in another executable and granting unconfined execution rights,
|
||||
it is possible to bypass the mandatory
|
||||
constraints imposed on all confined processes.
|
||||
For more information on what is constrained, see the
|
||||
subdomain(7) man page.
|
||||
<br><br> <b>Discrete Profile execute mode</b><br>
|
||||
This mode requires that a discrete security profile is
|
||||
defined for a resource executed at a AppArmor domain
|
||||
transition. If there is no profile defined then the
|
||||
access will be denied. Incompatible with Inherit and
|
||||
Unconstrained execute entries.
|
||||
<br>
|
||||
<br>
|
||||
<b>Link mode</b><br>
|
||||
Allows the program to be able to create and remove a
|
||||
link with this name (including symlinks). When a link
|
||||
is created, the file that is being linked to MUST have
|
||||
the same access permissions as the link being created
|
||||
(with the exception that the destination does not have
|
||||
to have link access.) Link access is required for
|
||||
unlinking a file.
|
||||
<br>
|
||||
<br>
|
||||
<b>Globbing</b>
|
||||
<br>
|
||||
<br>
|
||||
File resources may be specified with a globbing syntax
|
||||
similar to that used by popular shells, such as csh(1),
|
||||
bash(1), zsh(1).
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<li><b>*</b> can substitute for any number of characters, excepting
|
||||
'/'<li>
|
||||
|
||||
<li><b>**</b> can substitute for any number of characters, including '/'</li>
|
||||
|
||||
|
||||
<li><b>?</b> can substitute for any single character excepting '/'</li>
|
||||
<li><b>[abc]</b> will substitute for the single character a, b, or c</li>
|
||||
<li><b>[a-c]</b> will substitute for the single character a, b, or c</li>
|
||||
<li><b>{ab,cd}</b> will expand to one rule to match ab, one rule to match cd</li>\n
|
||||
</ul>");
|
||||
|
||||
list<string> headers = agent_data["headers"]:[];
|
||||
list<string> options = agent_data["options"]:[];
|
||||
list<string> functions = agent_data["functions"]:["CMD_ABORT"];
|
||||
string explanation = agent_data["explanation"]:"";
|
||||
string default_button = agent_data["default"]:"NO_DEFAULT";
|
||||
integer selected = agent_data["selected"]:0;
|
||||
|
||||
integer idx = 0;
|
||||
|
||||
// build up the list of headers
|
||||
term ui_headers = `VBox(`VSpacing(0.5));
|
||||
while(idx < size(headers)) {
|
||||
string field = headers[idx]:"MISSING FIELD";
|
||||
string value = (string) tostring(headers[idx+1]:"MISSING VALUE");
|
||||
ui_headers = add(ui_headers, `Left(`HBox(`Heading(field), `HSpacing(0.5), `HWeight(75, `Label(value)))));
|
||||
idx = idx + 2;
|
||||
}
|
||||
ui_headers = add(ui_headers, `VSpacing(0.5));
|
||||
|
||||
// build up the option list if we have one
|
||||
idx = 0;
|
||||
term ui_options = `VBox(`VSpacing(0.5));
|
||||
foreach (string option, options, ``{
|
||||
ui_options = add(ui_options, `Left(`RadioButton(`id(idx), option)));
|
||||
idx = idx + 1;
|
||||
});
|
||||
ui_options = add(ui_options, `VSpacing(0.5));
|
||||
|
||||
// build up the set of buttons for the different actions we support
|
||||
term ui_functions = `HBox( `HSpacing(`opt(`hstretch), 0.1) );
|
||||
foreach (string function, functions, ``{
|
||||
if((function != "CMD_ABORT") && (function != "CMD_FINISHED")) {
|
||||
string buttontext = CMDS[function]:"MISSING BUTTON TEXT";
|
||||
ui_functions = add(ui_functions, `HCenter(`PushButton(`id(function), buttontext)));
|
||||
}
|
||||
});
|
||||
ui_functions = add(ui_functions, `HSpacing(`opt(`hstretch), 0.1));
|
||||
|
||||
// throw it all together
|
||||
term contents = `VBox(
|
||||
`Top(
|
||||
`VBox(
|
||||
ui_headers,
|
||||
`Label(explanation),
|
||||
`RadioButtonGroup(ui_options),
|
||||
`VSpacing(`opt(`vstretch), 1),
|
||||
ui_functions
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// update the ui to reflect our new form state...
|
||||
Wizard::SetContents(title, contents, helptext, false, true);
|
||||
// fix up the label on the next/finish button
|
||||
Wizard::SetNextButton(`next, Label::FinishButton() );
|
||||
|
||||
// select and enable to correct buttons
|
||||
idx = 0;
|
||||
foreach (string option, options, ``{
|
||||
UI::ChangeWidget (`id(idx), `Value, selected == idx);
|
||||
idx = idx + 1;
|
||||
});
|
||||
|
||||
// set the focus to be the default action, if we have one
|
||||
if(default_button != "NO_DEFAULT") {
|
||||
UI::SetFocus(`id (default_button));
|
||||
}
|
||||
|
||||
// wait for user input
|
||||
any ret = Wizard::UserInput();
|
||||
|
||||
map answers = $[ ];
|
||||
|
||||
// figure out which button they pressed
|
||||
if (ret == `abort) {
|
||||
answers["selection"] = "CMD_ABORT";
|
||||
} else if (ret == `next) {
|
||||
answers["selection"] = "CMD_FINISHED";
|
||||
} else {
|
||||
foreach (string function, functions, ``{
|
||||
if(ret == function) {
|
||||
answers["selection"] = function;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// figure out which option was selected
|
||||
idx = 0;
|
||||
foreach (string option, options, ``{
|
||||
if(UI::QueryWidget(`id(idx), `Value) == true) {
|
||||
answers["selected"] = option;
|
||||
}
|
||||
idx = idx + 1;
|
||||
});
|
||||
|
||||
// tell the backend what they did
|
||||
SCR::Write(.logprof, answers);
|
||||
|
||||
} else if (type == "dialog-yesno") {
|
||||
|
||||
string question = agent_data["question"]:"MISSING QUESTION";
|
||||
string default_ans = agent_data["default"]:"n";
|
||||
|
||||
symbol focus = `focus_no;
|
||||
if(default_ans == "y") {
|
||||
focus = `focus_yes;
|
||||
}
|
||||
|
||||
map answers = $[ ];
|
||||
if(Popup::AnyQuestion(Popup::NoHeadline(), question, _("&Yes"), _("&No"), focus)) {
|
||||
answers["answer"] = "y";
|
||||
} else {
|
||||
answers["answer"] = "n";
|
||||
}
|
||||
|
||||
# write the answers for the last dialog
|
||||
boolean written = SCR::Write(.logprof, answers);
|
||||
|
||||
} else if (type == "dialog-getstring") {
|
||||
|
||||
string label = agent_data["label"]:"MISSING LABEL";
|
||||
string default_value = agent_data["default"]:"MISSING DEFAULT";
|
||||
|
||||
term dialog = `VBox(
|
||||
`TextEntry(`id (`stringfield), label, default_value),
|
||||
`HBox(
|
||||
`HWeight(1, `PushButton(`id(`okay), `opt(`default, `key_F10), _("&Okay"))),
|
||||
`HSpacing(2),
|
||||
`HWeight(1, `PushButton(`id(`cancel), `opt(`key_F9), _("&Cancel")))
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
UI::OpenDialog(dialog);
|
||||
UI::SetFocus(`id(`stringfield));
|
||||
|
||||
any poo = UI::UserInput();
|
||||
|
||||
map answers = $[ ];
|
||||
if(poo == `okay) {
|
||||
answers["string"] = (string) UI::QueryWidget(`id(`stringfield), `Value);
|
||||
} else {
|
||||
answers["string"] = "";
|
||||
}
|
||||
|
||||
UI::CloseDialog();
|
||||
|
||||
# write the answers for the last dialog
|
||||
boolean written = SCR::Write(.logprof, answers);
|
||||
|
||||
} else if (type == "dialog-getfile") {
|
||||
|
||||
string description = agent_data["description"]:"GETFILE: MISSING DESCRIPTION";
|
||||
string file_label = agent_data["file_label"]:"GETFILE: MISSING FILE:LABEL";
|
||||
string okay_label = agent_data["okay_label"]:"GETFILE: MISSING OKAY_LABEL";
|
||||
string cancel_label = agent_data["cancel_label"]:"GETFILE: MISSING CANCEL_LABEL";
|
||||
string browse_desc = agent_data["browse_desc"]:"GETFILE: MISSING BROWSE_DESC";
|
||||
|
||||
term dialog = `VBox(
|
||||
`Top(
|
||||
`VBox(
|
||||
`VSpacing(1),
|
||||
`Left(`Label(description)),
|
||||
`VSpacing(0.5),
|
||||
`Left(`TextEntry(`id(`filename), file_label, "")),
|
||||
`VSpacing(`opt(`vstretch), 0.25)
|
||||
)
|
||||
),
|
||||
`HBox( `HCenter(`PushButton(`id(`browse), _("&Browse")))),
|
||||
`HBox(
|
||||
`HSpacing(`opt(`hstretch), 0.1),
|
||||
`HCenter(`PushButton(`id(`okay), `opt(`default), okay_label)),
|
||||
`HCenter(`PushButton(`id(`cancel), cancel_label)),
|
||||
`HSpacing(`opt(`hstretch), 0.1),
|
||||
`VSpacing(1)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
UI::OpenDialog(dialog);
|
||||
|
||||
map<string,string> answers = $[ ];
|
||||
any poo = false;
|
||||
repeat {
|
||||
UI::SetFocus(`id(`filename));
|
||||
|
||||
poo = UI::UserInput();
|
||||
if(poo == `okay) {
|
||||
answers["answer"] = "okay";
|
||||
answers["filename"] = (string) UI::QueryWidget(`id(`filename), `Value);
|
||||
} else if(poo == `cancel) {
|
||||
answers["answer"] = "cancel";
|
||||
} else if ( poo == `browse ) {
|
||||
string selectfilename = UI::AskForExistingFile( "/", "", browse_desc);
|
||||
UI::ChangeWidget(`id(`filename), `Value, selectfilename);
|
||||
}
|
||||
} until ((poo == `okay) || (poo == `cancel));
|
||||
|
||||
UI::CloseDialog();
|
||||
|
||||
// tell the backend what they picked
|
||||
boolean written = SCR::Write(.logprof, answers);
|
||||
|
||||
} else if (type == "dialog-error") {
|
||||
|
||||
string message = agent_data["message"]:"MISSING QUESTION";
|
||||
|
||||
Popup::Error(message);
|
||||
|
||||
map answers = $[ ];
|
||||
answers["answer"] = "okay";
|
||||
|
||||
// tell the backend that the user has acknowledged the error
|
||||
boolean written = SCR::Write(.logprof, answers);
|
||||
|
||||
} else if (type == "final_shutdown") {
|
||||
done = true;
|
||||
|
||||
map answers = $[ ];
|
||||
answers["type"] = "shutdown_acknowledge";
|
||||
answers["status"] = "shutting_down";
|
||||
|
||||
// tell the backend that we're shutting down also
|
||||
boolean written = SCR::Write(.logprof, answers);
|
||||
|
||||
} else {
|
||||
|
||||
string errortext = "Email support@novell.com: " + type;
|
||||
Popup::Error(errortext);
|
||||
done = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
} until ( done == true);
|
||||
|
||||
Wizard::CloseDialog();
|
||||
|
||||
}
|
92
management/yastui/src/clients/SD_AddProfile.ycp
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* ------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2002-2006 Novell/SUSE
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License published by the Free Software Foundation.
|
||||
*
|
||||
------------------------------------------------------------------*/
|
||||
{
|
||||
import "Wizard";
|
||||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
include "subdomain/profile_dialogs.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
// Globalz
|
||||
|
||||
define boolean CreateNewProfile() {
|
||||
string selectfilename = "";
|
||||
while ( true ) {
|
||||
selectfilename = UI::AskForExistingFile( "/", "", _("Select File To Generate A Profile for") );
|
||||
// Check for cancel in the file choose dialog
|
||||
if ( selectfilename == nil ) {
|
||||
return false;
|
||||
}
|
||||
Settings["CURRENT_PROFILE"] = selectfilename;
|
||||
boolean profile = (boolean) SCR::Read (.subdomain_profiles.new, selectfilename);
|
||||
if ( profile == false && Popup::YesNoHeadline( _("Profile for ") + selectfilename + _(" already exists."), _("Would you like to open this profile in editing mode?") ) ) {
|
||||
return true;
|
||||
}
|
||||
Settings["NEW_PROFILE"] = selectfilename;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Setup and run the Wizard
|
||||
//
|
||||
define any MainSequence() ``{
|
||||
|
||||
map profiles = nil;
|
||||
map aliases = $[
|
||||
"showprofile" : ``(DisplayProfileForm(Settings["CURRENT_PROFILE"]:"", false))
|
||||
];
|
||||
|
||||
map sequence = $[
|
||||
"ws_start" : "showprofile",
|
||||
"showprofile" : $[
|
||||
`abort : `abort,
|
||||
`next : `finish,
|
||||
`finish : `finish,
|
||||
],
|
||||
];
|
||||
|
||||
boolean created_new_profile = CreateNewProfile();
|
||||
if ( created_new_profile == false ) {
|
||||
remove( Settings, "NEW_PROFILE");
|
||||
remove( Settings, "CURRENT_PROFILE");
|
||||
return (any) `abort;
|
||||
}
|
||||
map new_profile = (map) SCR::Read (.subdomain_profiles, Settings["CURRENT_PROFILE"]:"" );
|
||||
Settings["PROFILE_MAP"] = new_profile;
|
||||
Wizard::CreateDialog();
|
||||
Wizard::SetTitleIcon("apparmor/add_profile");
|
||||
any ret = Sequencer::Run(aliases, sequence);
|
||||
Wizard::CloseDialog();
|
||||
if ( ret == `abort ) {
|
||||
string profile_name = Settings["NEW_PROFILE"]:"";
|
||||
any result = SCR::Write(.subdomain_profiles.delete, profile_name);
|
||||
}
|
||||
Settings = remove( Settings, "NEW_PROFILE");
|
||||
Settings = remove( Settings, "CURRENT_PROFILE");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// YEAH BABY RUN BABY RUN
|
||||
//
|
||||
any ret = nil;
|
||||
if (!installAppArmorPackages()) {
|
||||
return ret;
|
||||
}
|
||||
ret = MainSequence();
|
||||
return ret;
|
||||
}
|
||||
|
73
management/yastui/src/clients/SD_DeleteProfile.ycp
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* ------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2002-2006 Novell/SUSE
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License published by the Free Software Foundation.
|
||||
*
|
||||
------------------------------------------------------------------*/
|
||||
{
|
||||
import "Wizard";
|
||||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
include "subdomain/profile_dialogs.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
// Globalz
|
||||
|
||||
define any DeleteProfileConfirmation() {
|
||||
string profilename = Settings["CURRENT_PROFILE"]:"";
|
||||
if (Popup::YesNoHeadline( _("Delete profile confirmation"), _("Are you
|
||||
sure you want to delete the profile ")
|
||||
+ profilename + _(" ?\nAfter this operation the AppArmor module will reload the profile set.") ) ) {
|
||||
y2milestone("Deleted " + profilename );
|
||||
boolean result = SCR::Write(.subdomain_profiles.delete, profilename);
|
||||
any result2 = SCR::Write(.subdomain_profiles.reload, "-");
|
||||
}
|
||||
return `finish;
|
||||
}
|
||||
|
||||
define any MainSequence() ``{
|
||||
|
||||
//
|
||||
// Read the profiles from the SCR agent
|
||||
map profiles = (map) SCR::Read (.subdomain_profiles, "all");
|
||||
|
||||
map aliases = $[
|
||||
"chooseprofile" : ``(SelectProfileForm(profiles, _("Please make a selection from the listed profiles and press Next to delete the profile.<p>"), _("Delete Profile - Choose profile to delete"), "subdomain/delete_profile")),
|
||||
"deleteprofile" : ``(DeleteProfileConfirmation()),
|
||||
];
|
||||
|
||||
map sequence = $[
|
||||
"ws_start" : "chooseprofile",
|
||||
"chooseprofile" : $[
|
||||
`abort : `abort,
|
||||
`next : "deleteprofile",
|
||||
`finish : `next,
|
||||
],
|
||||
];
|
||||
|
||||
Wizard::CreateDialog();
|
||||
Wizard::SetTitleIcon("apparmor/delete_profile");
|
||||
any ret = Sequencer::Run(aliases, sequence);
|
||||
Wizard::CloseDialog();
|
||||
Settings = remove( Settings, "CURRENT_PROFILE");
|
||||
Settings = remove( Settings, "PROFILE_MAP");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// YEAH BABY RUN BABY RUN
|
||||
//
|
||||
any ret = nil;
|
||||
if (!installAppArmorPackages()) {
|
||||
return ret;
|
||||
}
|
||||
ret = MainSequence();
|
||||
return ret;
|
||||
}
|
||||
|
76
management/yastui/src/clients/SD_EditProfile.ycp
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* ------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2002-2006 Novell/SUSE
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License published by the Free Software Foundation.
|
||||
*
|
||||
------------------------------------------------------------------*/
|
||||
{
|
||||
import "Wizard";
|
||||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
include "subdomain/profile_dialogs.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
// Globalz
|
||||
|
||||
|
||||
|
||||
define any MainSequence() ``{
|
||||
|
||||
//
|
||||
// Read the profiles from the SCR agent
|
||||
map profiles = (map) SCR::Read (.subdomain_profiles, "all");
|
||||
|
||||
map aliases = $[
|
||||
"showProfile" : ``(DisplayProfileForm(Settings["CURRENT_PROFILE"]:"", false)),
|
||||
"showHat" : ``(DisplayProfileForm(Settings["CURRENT_HAT"]:"", true)),
|
||||
"chooseProfile" : ``(SelectProfileForm(profiles, _("Please make a selection from the listed profiles and press Next to edit the profile.<p>"), _("Edit Profile - Choose profile to edit"), "apparmor/edit_profile" )),
|
||||
|
||||
];
|
||||
|
||||
map sequence = $[
|
||||
"ws_start" : "chooseProfile",
|
||||
"chooseProfile" : $[
|
||||
`abort : `abort,
|
||||
`next : "showProfile",
|
||||
`finish : `next,
|
||||
],
|
||||
"showProfile" : $[
|
||||
`abort : `abort,
|
||||
`next : `ws_finish,
|
||||
`showhat : "showHat",
|
||||
`finish : `next,
|
||||
],
|
||||
"showHat" : $[
|
||||
`abort : `abort,
|
||||
`next : "showProfile",
|
||||
`finish : `next,
|
||||
],
|
||||
];
|
||||
|
||||
Wizard::CreateDialog();
|
||||
Wizard::SetTitleIcon("apparmor/edit_profile");
|
||||
any ret = Sequencer::Run(aliases, sequence);
|
||||
Wizard::CloseDialog();
|
||||
Settings = remove( Settings, "CURRENT_PROFILE");
|
||||
Settings = remove( Settings, "PROFILE_MAP");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// YEAH BABY RUN BABY RUN
|
||||
//
|
||||
any ret = nil;
|
||||
if (!installAppArmorPackages()) {
|
||||
return ret;
|
||||
}
|
||||
ret = MainSequence();
|
||||
return ret;
|
||||
}
|
||||
|
124
management/yastui/src/clients/SD_Report.ycp
Normal file
|
@ -0,0 +1,124 @@
|
|||
/* ------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2002-2006 Novell/SUSE
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License published by the Free Software Foundation.
|
||||
*
|
||||
------------------------------------------------------------------*/
|
||||
{
|
||||
|
||||
import "Wizard";
|
||||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
include "subdomain/reporting_dialogues.ycp";
|
||||
include "subdomain/report_helptext.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
// Globalz
|
||||
|
||||
define any mainSequence() ``{
|
||||
|
||||
// Read the profiles from the SCR agent
|
||||
map aliases = $[
|
||||
"mainreport" : ``(mainReportForm()),
|
||||
"configreport" : ``(reportConfigForm()),
|
||||
"reportview" : ``(mainArchivedReportForm()),
|
||||
"schedReport" : ``(displaySchedForm()),
|
||||
"viewreport" : ``(displayArchForm()),
|
||||
"runReport" : ``(displayRunForm())
|
||||
/*
|
||||
"addSched" : ``(addSchedForm()),
|
||||
"editSched" : ``(editSchedForm()),
|
||||
"delSched" : ``(delSchedForm())
|
||||
*/
|
||||
];
|
||||
|
||||
map sequence = $[
|
||||
"ws_start" : "schedReport",
|
||||
"mainreport" : $[
|
||||
`back : `back,
|
||||
`abort : `abort,
|
||||
`next : `finish,
|
||||
`schedrep: "schedReport",
|
||||
`finish : `ws_finish
|
||||
],
|
||||
"schedReport": $[
|
||||
`back : `ws_start,
|
||||
`abort : `abort,
|
||||
// `add : "mainreport",
|
||||
// `edit : "editSched",
|
||||
// `del : "delSched",
|
||||
`viewrep : "viewreport",
|
||||
`runrep : "runReport",
|
||||
`next : "runReport",
|
||||
`finish : `ws_finish
|
||||
],
|
||||
/*
|
||||
"addSched" : $[
|
||||
`back : "schedReport",
|
||||
`abort : `abort,
|
||||
`save : `finish,
|
||||
`finish : `ws_finish
|
||||
],
|
||||
"editSched" : $[
|
||||
`back : "schedReport",
|
||||
`abort : `abort,
|
||||
`save : `finish,
|
||||
`finish : `ws_finish
|
||||
],
|
||||
"delSched" : $[
|
||||
`back : "schedReport",
|
||||
`abort : `abort,
|
||||
`save : `finish,
|
||||
`finish : `ws_finish
|
||||
],
|
||||
*/
|
||||
"viewreport" : $[
|
||||
//`back : "viewreport",
|
||||
`back : "mainreport",
|
||||
`abort : `abort,
|
||||
//`next : `finish,
|
||||
`next : "mainreport",
|
||||
`finish : `ws_finish
|
||||
],
|
||||
"runReport": $[
|
||||
//`back : "runReport",
|
||||
`back : `back,
|
||||
`abort : `abort,
|
||||
`next : `finish,
|
||||
`finish : `ws_finish
|
||||
],
|
||||
"configreport" : $[
|
||||
`back : `back,
|
||||
`abort : `abort,
|
||||
`next : "reportview",
|
||||
`finish : `ws_finish
|
||||
],
|
||||
"reportview" : $[
|
||||
`back : `back,
|
||||
`abort : `abort,
|
||||
`next : `finish,
|
||||
`finish : `ws_finish
|
||||
],
|
||||
];
|
||||
|
||||
Wizard::CreateDialog();
|
||||
Wizard::SetTitleIcon("apparmor/view_profile");
|
||||
any ret = Sequencer::Run(aliases, sequence);
|
||||
Wizard::CloseDialog();
|
||||
return ret;
|
||||
}
|
||||
|
||||
any ret = nil;
|
||||
if (!installAppArmorPackages()) {
|
||||
return ret;
|
||||
}
|
||||
ret = mainSequence();
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
64
management/yastui/src/clients/subdomain.ycp
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* ------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2002-2006 Novell/SUSE
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License published by the Free Software Foundation.
|
||||
*
|
||||
------------------------------------------------------------------*/
|
||||
|
||||
{
|
||||
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
/* The main () */
|
||||
y2milestone("----------------------------------------");
|
||||
y2milestone("Subdomain module started");
|
||||
|
||||
import "Label";
|
||||
import "Popup";
|
||||
import "Wizard";
|
||||
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
include "subdomain/sd-config.ycp";
|
||||
|
||||
if (!installAppArmorPackages()) {
|
||||
return;
|
||||
}
|
||||
|
||||
list<map> config_steps =
|
||||
[
|
||||
$[ "id": "subdomain", "label": _("Enable AppArmor Functions") ],
|
||||
];
|
||||
|
||||
list<map> steps = flatten( [ config_steps ] );
|
||||
|
||||
define symbol displayPage( integer no ) ``{
|
||||
|
||||
string current_id = lookup( steps[ no ]:nil, "id", "");
|
||||
symbol button = nil;
|
||||
|
||||
UI::WizardCommand(`SetCurrentStep( current_id ) );
|
||||
|
||||
if ( current_id == "subdomain") {
|
||||
//button = displaySubdomainConfig();
|
||||
button = displayAppArmorConfig();
|
||||
}
|
||||
|
||||
|
||||
|
||||
return button;
|
||||
|
||||
}
|
||||
|
||||
integer current_step = 0;
|
||||
symbol button = displayPage( current_step );
|
||||
|
||||
/* Finish */
|
||||
y2milestone("AppArmor module finished");
|
||||
y2milestone("----------------------------------------");
|
||||
|
||||
/* EOF */
|
||||
}
|
||||
|
20
management/yastui/src/clients/subdomain_no_impl.ycp
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* ------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2002-2005 Novell/SUSE
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License published by the Free Software Foundation.
|
||||
*
|
||||
------------------------------------------------------------------*/
|
||||
{
|
||||
import "Popup";
|
||||
import "Wizard";
|
||||
|
||||
//include "subdomain/prof-config.ycp";
|
||||
|
||||
/* BEGIN - This is just temporary filler */
|
||||
Popup::Message("This function is not implemented at this time");
|
||||
symbol button = (`ok);
|
||||
return button;
|
||||
}
|
23
management/yastui/src/desktop/SD_Reports.desktop
Normal file
|
@ -0,0 +1,23 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Categories=Qt;X-SuSE-YaST;X-SuSE-YaST-AppArmor;
|
||||
|
||||
X-KDE-ModuleType=Library
|
||||
X-KDE-RootOnly=true
|
||||
X-KDE-HasReadOnlyMode=true
|
||||
X-KDE-Library=yast2
|
||||
X-SuSE-YaST-Call=SD_Report
|
||||
|
||||
X-SuSE-YaST-Group=AppArmor
|
||||
X-SuSE-YaST-Argument=
|
||||
X-SuSE-YaST-RootOnly=true
|
||||
X-SuSE-YaST-AutoInst=none
|
||||
X-SuSE-YaST-Geometry=
|
||||
X-SuSE-YaST-SortKey=
|
||||
X-SuSE-YaST-AutoInstClonable=false
|
||||
|
||||
Icon=apparmor/view_profile
|
||||
Exec=/sbin/yast2 SD_Report
|
||||
|
||||
Name=AppArmor Reports
|
||||
GenericName=AppArmor Configuration
|
23
management/yastui/src/desktop/SD_add_profile.desktop
Normal file
|
@ -0,0 +1,23 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Categories=Qt;X-SuSE-YaST;X-SuSE-YaST-AppArmor;
|
||||
|
||||
X-KDE-ModuleType=Library
|
||||
X-KDE-RootOnly=true
|
||||
X-KDE-HasReadOnlyMode=true
|
||||
X-KDE-Library=yast2
|
||||
X-SuSE-YaST-Call=SD_AddProfile
|
||||
|
||||
X-SuSE-YaST-Group=AppArmor
|
||||
X-SuSE-YaST-Argument=
|
||||
X-SuSE-YaST-RootOnly=true
|
||||
X-SuSE-YaST-AutoInst=none
|
||||
X-SuSE-YaST-Geometry=
|
||||
X-SuSE-YaST-SortKey=
|
||||
X-SuSE-YaST-AutoInstClonable=false
|
||||
|
||||
Icon=apparmor/add_profile
|
||||
Exec=/sbin/yast2 SD_AddProfile
|
||||
|
||||
Name=Manually Add Profile
|
||||
GenericName=AppArmor Configuration
|
23
management/yastui/src/desktop/SD_control_panel.desktop
Normal file
|
@ -0,0 +1,23 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Categories=Qt;X-SuSE-YaST;X-SuSE-YaST-AppArmor;
|
||||
|
||||
X-KDE-ModuleType=Library
|
||||
X-KDE-RootOnly=true
|
||||
X-KDE-HasReadOnlyMode=true
|
||||
X-KDE-Library=yast2
|
||||
X-SuSE-YaST-Call=subdomain
|
||||
|
||||
X-SuSE-YaST-Group=AppArmor
|
||||
X-SuSE-YaST-Argument=
|
||||
X-SuSE-YaST-RootOnly=true
|
||||
X-SuSE-YaST-AutoInst=none
|
||||
X-SuSE-YaST-Geometry=
|
||||
X-SuSE-YaST-SortKey=
|
||||
X-SuSE-YaST-AutoInstClonable=false
|
||||
|
||||
Icon=apparmor/control_panel
|
||||
Exec=/sbin/yast2 subdomain
|
||||
|
||||
Name=AppArmor Control Panel
|
||||
GenericName=AppArmor Control Panel
|
23
management/yastui/src/desktop/SD_delete_profile.desktop
Normal file
|
@ -0,0 +1,23 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Categories=Qt;X-SuSE-YaST;X-SuSE-YaST-AppArmor;
|
||||
|
||||
X-KDE-ModuleType=Library
|
||||
X-KDE-RootOnly=true
|
||||
X-KDE-HasReadOnlyMode=true
|
||||
X-KDE-Library=yast2
|
||||
X-SuSE-YaST-Call=SD_DeleteProfile
|
||||
|
||||
X-SuSE-YaST-Group=AppArmor
|
||||
X-SuSE-YaST-Argument=
|
||||
X-SuSE-YaST-RootOnly=true
|
||||
X-SuSE-YaST-AutoInst=none
|
||||
X-SuSE-YaST-Geometry=
|
||||
X-SuSE-YaST-SortKey=
|
||||
X-SuSE-YaST-AutoInstClonable=false
|
||||
|
||||
Icon=apparmor/delete_profile
|
||||
Exec=/sbin/yast2 SD_DeleteProfile
|
||||
|
||||
Name=Delete Profile
|
||||
GenericName=AppArmor Configuration
|
23
management/yastui/src/desktop/SD_edit_profile.desktop
Normal file
|
@ -0,0 +1,23 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Categories=Qt;X-SuSE-YaST;X-SuSE-YaST-AppArmor;
|
||||
|
||||
X-KDE-ModuleType=Library
|
||||
X-KDE-RootOnly=true
|
||||
X-KDE-HasReadOnlyMode=true
|
||||
X-KDE-Library=yast2
|
||||
X-SuSE-YaST-Call=SD_EditProfile
|
||||
|
||||
X-SuSE-YaST-Group=AppArmor
|
||||
X-SuSE-YaST-Argument=
|
||||
X-SuSE-YaST-RootOnly=true
|
||||
X-SuSE-YaST-AutoInst=none
|
||||
X-SuSE-YaST-Geometry=
|
||||
X-SuSE-YaST-SortKey=
|
||||
X-SuSE-YaST-AutoInstClonable=false
|
||||
|
||||
Icon=apparmor/edit_profile
|
||||
Exec=/sbin/yast2 SD_EditProfile
|
||||
|
||||
Name=Edit Profile
|
||||
GenericName=AppArmor Configuration
|
23
management/yastui/src/desktop/SD_genprof.desktop
Normal file
|
@ -0,0 +1,23 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Categories=Qt;X-SuSE-YaST;X-SuSE-YaST-AppArmor;
|
||||
|
||||
X-KDE-ModuleType=Library
|
||||
X-KDE-RootOnly=true
|
||||
X-KDE-HasReadOnlyMode=true
|
||||
X-KDE-Library=yast2
|
||||
X-SuSE-YaST-Call=GenProf
|
||||
|
||||
X-SuSE-YaST-Group=AppArmor
|
||||
X-SuSE-YaST-Argument=
|
||||
X-SuSE-YaST-RootOnly=true
|
||||
X-SuSE-YaST-AutoInst=none
|
||||
X-SuSE-YaST-Geometry=
|
||||
X-SuSE-YaST-SortKey=
|
||||
X-SuSE-YaST-AutoInstClonable=false
|
||||
|
||||
Icon=apparmor/creation_wizzard
|
||||
Exec=/sbin/yast2 GenProf
|
||||
|
||||
Name=Add Profile Wizard
|
||||
GenericName=Profile Wizard
|
23
management/yastui/src/desktop/SD_logprof.desktop
Normal file
|
@ -0,0 +1,23 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Categories=Qt;X-SuSE-YaST;X-SuSE-YaST-AppArmor;
|
||||
|
||||
X-KDE-ModuleType=Library
|
||||
X-KDE-RootOnly=true
|
||||
X-KDE-HasReadOnlyMode=true
|
||||
X-KDE-Library=yast2
|
||||
X-SuSE-YaST-Call=LogProf
|
||||
|
||||
X-SuSE-YaST-Group=AppArmor
|
||||
X-SuSE-YaST-Argument=
|
||||
X-SuSE-YaST-RootOnly=true
|
||||
X-SuSE-YaST-AutoInst=none
|
||||
X-SuSE-YaST-Geometry=
|
||||
X-SuSE-YaST-SortKey=
|
||||
X-SuSE-YaST-AutoInstClonable=false
|
||||
|
||||
Icon=apparmor/update_wizzard
|
||||
Exec=/sbin/yast2 LogProf
|
||||
|
||||
Name=Update Profile Wizard
|
||||
GenericName=Update Profiles
|
16
management/yastui/src/desktop/groups/apparmor.desktop
Normal file
|
@ -0,0 +1,16 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Categories=Qt;X-SuSE-YaST-AppArmor;
|
||||
|
||||
X-KDE-ModuleType=Library
|
||||
X-KDE-RootOnly=true
|
||||
X-KDE-HasReadOnlyMode=true
|
||||
X-KDE-Library=yast2
|
||||
|
||||
X-SuSE-YaST-Group=AppArmor
|
||||
X-SuSE-YaST-SortKey=50
|
||||
|
||||
OnlyShowIn=X-SuSE-YaST;
|
||||
Icon=apparmor/app_armor
|
||||
|
||||
Name=Novell AppArmor
|
BIN
management/yastui/src/icons/22x22/add_profile.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
management/yastui/src/icons/22x22/control_panel.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
management/yastui/src/icons/22x22/creation_wizzard.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
management/yastui/src/icons/22x22/delete_profile.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
management/yastui/src/icons/22x22/edit_profile.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
management/yastui/src/icons/22x22/update_wizzard.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
management/yastui/src/icons/22x22/view_profile.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
management/yastui/src/icons/32x32/add_profile.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
management/yastui/src/icons/32x32/app_armor.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
management/yastui/src/icons/32x32/control_panel.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
management/yastui/src/icons/32x32/creation_wizzard.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
management/yastui/src/icons/32x32/delete_profile.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
management/yastui/src/icons/32x32/edit_profile.png
Normal file
After Width: | Height: | Size: 2.1 KiB |