Remove unnecessary and unused files from git
This commit is contained in:
parent
9cef10b755
commit
b1ef7171b6
820
Changelog
820
Changelog
@ -1,820 +0,0 @@
|
|||||||
- Unconditional staff and user oidentd home config access from Dominick Grift.
|
|
||||||
- Conditional mmap_zero support from Dominick Grift.
|
|
||||||
- Added devtmpfs support.
|
|
||||||
- Dbadm updates from KaiGai Kohei.
|
|
||||||
- Virtio disk file context update from Mika Pfluger.
|
|
||||||
- Increase bindreservport range to 512-1024 in corenetwork, from Dan Walsh.
|
|
||||||
- Add JIT usage for freshclam.
|
|
||||||
- Remove ethereal module since the application was renamed to wireshark.
|
|
||||||
- Remove duplicate/redundant rules, from Russell Coker.
|
|
||||||
- Increased default number of categories to 1024, from Russell Coker.
|
|
||||||
- Added modules:
|
|
||||||
accountsd (Dan Walsh)
|
|
||||||
cgroup (Dominick Grift)
|
|
||||||
kdumpgui (Dan Walsh)
|
|
||||||
livecd (Dan Walsh)
|
|
||||||
mojomojo (Lain Arnell)
|
|
||||||
sambagui (Dan Walsh)
|
|
||||||
shutdown (Dan Walsh)
|
|
||||||
|
|
||||||
* Mon May 24 2010 Chris PeBenito <selinux@tresys.com> - 2.20100524
|
|
||||||
- Merged a significant portion of Fedora policy.
|
|
||||||
- Move rules from mta mailserver delivery from interface to .te to use
|
|
||||||
attributes.
|
|
||||||
- Remove concept of users from terminal module interfaces since the
|
|
||||||
attributes are not specific to users.
|
|
||||||
- Add non-drawing X client support, for consolekit usage.
|
|
||||||
- Misc Gentoo fixes from Chris Richards.
|
|
||||||
- AFS and abrt fixes from Dominick Grift.
|
|
||||||
- Improved the XML docs of 55 most-used interfaces.
|
|
||||||
- Apcupsd and amavis fixes from Dominick Grift.
|
|
||||||
- Fix network_port() in corenetwork to correctly handle port ranges.
|
|
||||||
- SE-Postgresql updates from KaiGai Kohei.
|
|
||||||
- X object manager revisions from Eamon Walsh.
|
|
||||||
- Added modules:
|
|
||||||
aisexec (Dan Walsh)
|
|
||||||
chronyd (Miroslav Grepl)
|
|
||||||
cobbler (Dominick Grift)
|
|
||||||
corosync (Dan Walsh)
|
|
||||||
dbadm (KaiGai Kohei)
|
|
||||||
denyhosts (Dan Walsh)
|
|
||||||
nut (Stefan Schulze Frielinghaus, Miroslav Grepl)
|
|
||||||
likewise (Scott Salley)
|
|
||||||
plymouthd (Dan Walsh)
|
|
||||||
pyicqt (Stefan Schulze Frielinghaus)
|
|
||||||
rhcs (Dan Walsh)
|
|
||||||
rgmanager (Dan Walsh)
|
|
||||||
sectoolm (Miroslav Grepl)
|
|
||||||
usbmuxd (Dan Walsh)
|
|
||||||
vhostmd (Dan Walsh)
|
|
||||||
|
|
||||||
* Tue Nov 17 2009 Chris PeBenito <selinux@tresys.com> - 2.20091117
|
|
||||||
- Add separate x_pointer and x_keyboard classes inheriting from x_device.
|
|
||||||
From Eamon Walsh.
|
|
||||||
- Deprecated the userdom_xwindows_client_template().
|
|
||||||
- Misc Gentoo fixes from Corentin Labbe.
|
|
||||||
- Debian policykit fixes from Martin Orr.
|
|
||||||
- Fix unconfined_r use of unconfined_java_t.
|
|
||||||
- Add missing x_device rules for XI2 functions, from Eamon Walsh.
|
|
||||||
- Add missing rules to make unconfined_cronjob_t a valid cron job domain.
|
|
||||||
- Add btrfs and ext4 to labeling targets.
|
|
||||||
- Fix infrastructure to expand macros in initrc_context when installing.
|
|
||||||
- Handle unix_chkpwd usage by useradd and groupadd.
|
|
||||||
- Add missing compatibility aliases for xdm_xserver*_t types.
|
|
||||||
- Added modules:
|
|
||||||
abrt (Dan Walsh)
|
|
||||||
dkim (Stefan Schulze Frielinghaus)
|
|
||||||
gitosis (Miroslav Grepl)
|
|
||||||
gnomeclock (Dan Walsh)
|
|
||||||
hddtemp (Dan Walsh)
|
|
||||||
kdump (Dan Walsh)
|
|
||||||
modemmanager(Dan Walsh)
|
|
||||||
nslcd (Dan Walsh)
|
|
||||||
puppet (Craig Grube)
|
|
||||||
rtkit (Dan Walsh)
|
|
||||||
seunshare (Dan Walsh)
|
|
||||||
shorewall (Dan Walsh)
|
|
||||||
tgtd (Matthew Ife)
|
|
||||||
tuned (Miroslav Grepl)
|
|
||||||
xscreensaver (Corentin Labbe)
|
|
||||||
|
|
||||||
* Thu Jul 30 2009 Chris PeBenito <selinux@tresys.com> - 2.20090730
|
|
||||||
- Gentoo fixes for init scripts and system startup.
|
|
||||||
- Remove read_default_t tunable.
|
|
||||||
- Greylist milter from Paul Howarth.
|
|
||||||
- Crack db access for su to handle password expiration, from Brandon Whalen.
|
|
||||||
- Misc fixes for unix_update from Brandon Whalen.
|
|
||||||
- Add x_device permissions for XI2 functions, from Eamon Walsh.
|
|
||||||
- MLS constraints for the x_selection class, from Eamon Walsh.
|
|
||||||
- Postgresql updates from KaiGai Kohei.
|
|
||||||
- Milter state directory patch from Paul Howarth.
|
|
||||||
- Add MLS constrains for ingress/egress and secmark from Paul Moore.
|
|
||||||
- Drop write permission from fs_read_rpc_sockets().
|
|
||||||
- Remove unused udev_runtime_t type.
|
|
||||||
- Patch for RadSec port from Glen Turner.
|
|
||||||
- Enable network_peer_controls policy capability from Paul Moore.
|
|
||||||
- Btrfs xattr support from Paul Moore.
|
|
||||||
- Add db_procedure install permission from KaiGai Kohei.
|
|
||||||
- Add support for network interfaces with access controlled by a Boolean
|
|
||||||
from the CLIP project.
|
|
||||||
- Several fixes from the CLIP project.
|
|
||||||
- Add support for labeled Booleans.
|
|
||||||
- Remove node definitions and change node usage to generic nodes.
|
|
||||||
- Add kernel_service access vectors, from Stephen Smalley.
|
|
||||||
- Added modules:
|
|
||||||
certmaster (Dan Walsh)
|
|
||||||
cpufreqselector (Dan Walsh)
|
|
||||||
devicekit (Dan Walsh)
|
|
||||||
fprintd (Dan Walsh)
|
|
||||||
git (Dan Walsh)
|
|
||||||
gpsd (Miroslav Grepl)
|
|
||||||
guest (Dan Walsh)
|
|
||||||
ifplugd (Dan Walsh)
|
|
||||||
lircd (Miroslav Grepl)
|
|
||||||
logadm (Dan Walsh)
|
|
||||||
pads (Dan Walsh)
|
|
||||||
pingd (Dan Walsh)
|
|
||||||
policykit (Dan Walsh)
|
|
||||||
pulseaudio (Dan Walsh)
|
|
||||||
psad (Dan Walsh)
|
|
||||||
portreserve (Dan Walsh)
|
|
||||||
sssd (Dan Walsh)
|
|
||||||
ulogd (Dan Walsh)
|
|
||||||
varnishd (Dan Walsh)
|
|
||||||
webadm (Dan Walsh)
|
|
||||||
wm (Dan Walsh)
|
|
||||||
xguest (Dan Walsh)
|
|
||||||
zosremote (Dan Walsh)
|
|
||||||
|
|
||||||
* Wed Dec 10 2008 Chris PeBenito <selinux@tresys.com> - 2.20081210
|
|
||||||
- Fix consistency of audioentropy and iscsi module naming.
|
|
||||||
- Debian file context fix for xen from Russell Coker.
|
|
||||||
- Xserver MLS fix from Eamon Walsh.
|
|
||||||
- Add omapi port for dhcpcd.
|
|
||||||
- Deprecate per-role templates and rolemap support.
|
|
||||||
- Implement user-based access control for use as role separations.
|
|
||||||
- Move shared library calls from individual modules to the domain module.
|
|
||||||
- Enable open permission checks policy capability.
|
|
||||||
- Remove hierarchy from portage module as it is not a good example of
|
|
||||||
hieararchy.
|
|
||||||
- Remove enableaudit target from modular build as semodule -DB supplants it.
|
|
||||||
- Added modules:
|
|
||||||
milter (Paul Howarth)
|
|
||||||
|
|
||||||
* Tue Oct 14 2008 Chris PeBenito <selinux@tresys.com> - 20081014
|
|
||||||
- Debian update for NetworkManager/wpa_supplicant from Martin Orr.
|
|
||||||
- Logrotate and Bind updates from Vaclav Ovsik.
|
|
||||||
- Init script file and domain support.
|
|
||||||
- Glibc 2.7 fix from Vaclav Ovsik.
|
|
||||||
- Samba/winbind update from Mike Edenfield.
|
|
||||||
- Policy size optimization with a non-security file attribute from James
|
|
||||||
Carter.
|
|
||||||
- Database labeled networking update from KaiGai Kohei.
|
|
||||||
- Several misc changes from the Fedora policy, cherry picked by David
|
|
||||||
Hardeman.
|
|
||||||
- Large whitespace fix from Dominick Grift.
|
|
||||||
- Pam_mount fix for local login from Stefan Schulze Frielinghaus.
|
|
||||||
- Issuing commands to upstart is over a datagram socket, not the initctl
|
|
||||||
named pipe. Updated init_telinit() to match.
|
|
||||||
- Added modules:
|
|
||||||
cyphesis (Dan Walsh)
|
|
||||||
memcached (Dan Walsh)
|
|
||||||
oident (Dominick Grift)
|
|
||||||
w3c (Dan Walsh)
|
|
||||||
|
|
||||||
* Wed Jul 02 2008 Chris PeBenito <selinux@tresys.com> - 20080702
|
|
||||||
- Fix httpd_enable_homedirs to actually provide the access it is supposed to
|
|
||||||
provide.
|
|
||||||
- Add unused interface/template parameter metadata in XML.
|
|
||||||
- Patch to handle postfix data_directory from Vaclav Ovsik.
|
|
||||||
- SE-Postgresql policy from KaiGai Kohei.
|
|
||||||
- Patch for X.org dbus support from Martin Orr.
|
|
||||||
- Patch for labeled networking controls in 2.6.25 from Paul Moore.
|
|
||||||
- Module loading now requires setsched on kernel threads.
|
|
||||||
- Patch to allow gpg agent --write-env-file option from Vaclav Ovsik.
|
|
||||||
- X application data class from Eamon Walsh and Ted Toth.
|
|
||||||
- Move user roles into individual modules.
|
|
||||||
- Make hald_log_t a log file.
|
|
||||||
- Cryptsetup runs shell scripts. Patch from Martin Orr.
|
|
||||||
- Add file for enabling policy capabilities.
|
|
||||||
- Patch to fix leaky interface/template call depth calculator from Vaclav
|
|
||||||
Ovsik.
|
|
||||||
- Added modules:
|
|
||||||
kerneloops (Dan Walsh)
|
|
||||||
kismet (Dan Walsh)
|
|
||||||
podsleuth (Dan Walsh)
|
|
||||||
prelude (Dan Walsh)
|
|
||||||
qemu (Dan Walsh)
|
|
||||||
virt (Dan Walsh)
|
|
||||||
|
|
||||||
* Wed Apr 02 2008 Chris PeBenito <selinux@tresys.com> - 20080402
|
|
||||||
- Add core Security Enhanced X Windows support.
|
|
||||||
- Fix winbind socket connection interface for default location of the
|
|
||||||
sock_file.
|
|
||||||
- Add wireshark module based on ethereal module.
|
|
||||||
- Revise upstart support in init module to use a tunable, as upstart is now
|
|
||||||
used in Fedora too.
|
|
||||||
- Add iferror.m4 rather generate it out of the Makefiles.
|
|
||||||
- Definitions for open permisson on file and similar objects from Eric
|
|
||||||
Paris.
|
|
||||||
- Apt updates for ptys and logs, from Martin Orr.
|
|
||||||
- RPC update from Vaclav Ovsik.
|
|
||||||
- Exim updates on Debian from Devin Carrawy.
|
|
||||||
- Pam and samba updates from Stefan Schulze Frielinghaus.
|
|
||||||
- Backup update on Debian from Vaclav Ovsik.
|
|
||||||
- Cracklib update on Debian from Vaclav Ovsik.
|
|
||||||
- Label /proc/kallsyms with system_map_t.
|
|
||||||
- 64-bit capabilities from Stephen Smalley.
|
|
||||||
- Labeled networking peer object class updates.
|
|
||||||
|
|
||||||
* Fri Dec 14 2007 Chris PeBenito <selinux@tresys.com> - 20071214
|
|
||||||
- Patch for debian logrotate to handle syslogd-listfiles, from Vaclav Ovsik.
|
|
||||||
- Improve several tunables descriptions from Dan Walsh.
|
|
||||||
- Patch to clean up ns switch usage in the policy from Dan Walsh.
|
|
||||||
- More complete labeled networking infrastructure from KaiGai Kohei.
|
|
||||||
- Add interface for libselinux constructor, for libselinux-linked
|
|
||||||
SELinux-enabled programs.
|
|
||||||
- Patch to restructure user role templates to create restricted user roles
|
|
||||||
from Dan Walsh.
|
|
||||||
- Russian man page translations from Andrey Markelov.
|
|
||||||
- Remove unused types from dbus.
|
|
||||||
- Add infrastructure for managing all user web content.
|
|
||||||
- Deprecate some old file and dir permission set macros in favor of the
|
|
||||||
newer, more consistently-named macros.
|
|
||||||
- Patch to clean up unescaped periods in several file context entries from
|
|
||||||
Jan-Frode Myklebust.
|
|
||||||
- Merge shlib_t into lib_t.
|
|
||||||
- Merge strict and targeted policies. The policy will now behave like the
|
|
||||||
strict policy if the unconfined module is not present. If it is, it will
|
|
||||||
behave like the targeted policy. Added an unconfined role to have a mix
|
|
||||||
of confined and unconfined users.
|
|
||||||
- Added modules:
|
|
||||||
exim (Dan Walsh)
|
|
||||||
postfixpolicyd (Jan-Frode Myklebust)
|
|
||||||
|
|
||||||
* Fri Sep 28 2007 Chris PeBenito <selinux@tresys.com> - 20070928
|
|
||||||
- Add support for setting the unknown permissions handling.
|
|
||||||
- Fix XML building for external reference builds and headers builds.
|
|
||||||
- Patch to add missing requirements in userdomain interfaces from Shintaro
|
|
||||||
Fujiwara.
|
|
||||||
- Add tcpd_wrapped_domain() for services that use tcp wrappers.
|
|
||||||
- Update MLS constraints from LSPP evaluated policy.
|
|
||||||
- Allow initrc_t file descriptors to be inherited regardless of MLS level.
|
|
||||||
Accordingly drop MLS permissions from daemons that inherit from any level.
|
|
||||||
- Files and radvd updates from Stefan Schulze Frielinghaus.
|
|
||||||
- Deprecate mls_file_write_down() and mls_file_read_up(), replaced with
|
|
||||||
mls_write_all_levels() and mls_read_all_levels(), for consistency.
|
|
||||||
- Add make kernel and init ranged interfaces pass the range transition MLS
|
|
||||||
constraints. Also remove calls to mls_rangetrans_target() in modules that use
|
|
||||||
the kernel and init interfaces, since its redundant.
|
|
||||||
- Add interfaces for all MLS attributes except X object classes.
|
|
||||||
- Require all sensitivities and categories for MLS and MCS policies, not just
|
|
||||||
the low and high sensitivity and category.
|
|
||||||
- Database userspace object manager classes from KaiGai Kohei.
|
|
||||||
- Add third-party interface for Apache CGI.
|
|
||||||
- Add getserv and shmemserv nscd permissions.
|
|
||||||
- Add debian apcupsd binary location, from Stefan Schulze Frielinghaus.
|
|
||||||
- Added modules:
|
|
||||||
application
|
|
||||||
awstats (Stefan Schulze Frielinghaus)
|
|
||||||
bitlbee (Devin Carraway)
|
|
||||||
brctl (Dan Walsh)
|
|
||||||
|
|
||||||
* Fri Jun 29 2007 Chris PeBenito <selinux@tresys.com> - 20070629
|
|
||||||
- Fix incorrectly named files_lib_filetrans_shared_lib() interface in the
|
|
||||||
libraries module.
|
|
||||||
- Unified labeled networking policy from Paul Moore.
|
|
||||||
- Use netmsg initial SID for MLS-only Netlabel packets, from Paul Moore.
|
|
||||||
- Xen updates from Dan Walsh.
|
|
||||||
- Filesystem updates from Dan Walsh.
|
|
||||||
- Large samba update from Dan Walsh.
|
|
||||||
- Drop snmpd_etc_t.
|
|
||||||
- Confine sendmail and logrotate on targeted.
|
|
||||||
- Tunable connection to postgresql for users from KaiGai Kohei.
|
|
||||||
- Memprotect support patch from Stephen Smalley.
|
|
||||||
- Add logging_send_audit_msgs() interface and deprecate
|
|
||||||
send_audit_msgs_pattern().
|
|
||||||
- Openct updates patch from Dan Walsh.
|
|
||||||
- Merge restorecon into setfiles.
|
|
||||||
- Patch to begin separating out hald helper programs from Dan Walsh.
|
|
||||||
- Fixes for squid, dovecot, and snmp from Dan Walsh.
|
|
||||||
- Miscellaneous consolekit fixes from Dan Walsh.
|
|
||||||
- Patch to have avahi use the nsswitch interface rather than individual
|
|
||||||
permissions from Dan Walsh.
|
|
||||||
- Patch to dontaudit logrotate searching avahi pid directory from Dan Walsh.
|
|
||||||
- Patch to allow insmod to mount kvmfs and dontaudit rw unconfined_t pipes
|
|
||||||
to handle usage from userhelper from Dan Walsh.
|
|
||||||
- Patch to allow amavis to read spamassassin libraries from Dan Walsh.
|
|
||||||
- Patch to allow slocate to getattr other filesystems and directories on those
|
|
||||||
filesystems from Dan Walsh.
|
|
||||||
- Fixes for RHEL4 from the CLIP project.
|
|
||||||
- Replace the old lrrd fc entries with munin ones.
|
|
||||||
- Move program admin template usage out of userdom_admin_user_template() to
|
|
||||||
sysadm policy in userdomain.te to fix usage of the template for third
|
|
||||||
parties.
|
|
||||||
- Fix clockspeed_run_cli() declaration, it was incorrectly defined as a
|
|
||||||
template instead of an interface.
|
|
||||||
- Added modules:
|
|
||||||
amtu (Dan Walsh)
|
|
||||||
apcupsd (Dan Walsh)
|
|
||||||
rpcbind (Dan Walsh)
|
|
||||||
rwho (Nalin Dahyabhai)
|
|
||||||
|
|
||||||
* Tue Apr 17 2007 Chris PeBenito <selinux@tresys.com> - 20070417
|
|
||||||
- Patch for sasl's use of kerberos from Dan Walsh.
|
|
||||||
- Patches to confine ldconfig, udev, and insmod in the targeted policy from Dan Walsh.
|
|
||||||
- Man page updates from Dan Walsh.
|
|
||||||
- Two patches from Paul Moore to for ipsec to remove redundant rules and
|
|
||||||
have setkey read the config file.
|
|
||||||
- Move booleans and tunables to modules when it is only used in a single
|
|
||||||
module.
|
|
||||||
- Add support for tunables and booleans local to a module.
|
|
||||||
- Merge sbin_t and ls_exec_t into bin_t.
|
|
||||||
- Remove disable_trans booleans.
|
|
||||||
- Output different header sets for kernel and userland from flask headers.
|
|
||||||
- Marked the pax class as deprecated, changed it to userland so
|
|
||||||
it will be removed from the kernel.
|
|
||||||
- Stop including netfilter contexts by default.
|
|
||||||
- Add dontaudits for init fds and console to init_daemon_domain().
|
|
||||||
- Patch to allow gpg to create user keys dir.
|
|
||||||
- Patch to support kvmfs from Dan Walsh.
|
|
||||||
- Patch for misc fixes in sudo from Dan Walsh.
|
|
||||||
- Patch to fix netlabel recvfrom MLS constraint from Paul Moore.
|
|
||||||
- Patch for handling restart of nscd when ran from useradd, groupadd, and
|
|
||||||
admin passwd, from Dan Walsh.
|
|
||||||
- Patch for procmail, spamassassin, and pyzor updates from Dan Walsh.
|
|
||||||
- Patch for setroubleshoot for validating file contexts from Dan Walsh.
|
|
||||||
- Patch for gssd fixes from Dan Walsh.
|
|
||||||
- Patch for lvm fixes from Dan Walsh.
|
|
||||||
- Patch for ricci fixes from Dan Walsh.
|
|
||||||
- Patch for postfix lmtp labeling and pickup rule fix from Dan Walsh.
|
|
||||||
- Patch for kerberized telnet fixes from Dan Walsh.
|
|
||||||
- Patch for kerberized ftp and other ftp fixes from Dan Walsh.
|
|
||||||
- Patch for an additional wine executable from Dan Walsh.
|
|
||||||
- Eight patches for file contexts in games, wine, networkmanager, miscfiles,
|
|
||||||
corecommands, devices, and java from Dan Walsh.
|
|
||||||
- Add support for libselinux 2.0.5 init_selinuxmnt() changes.
|
|
||||||
- Patch for misc fixes to bluetooth from Dan Walsh.
|
|
||||||
- Patch for misc fixes to kerberos from Dan Walsh.
|
|
||||||
- Patch to start deprecating usercanread attribute from Ryan Bradetich.
|
|
||||||
- Add dccp_socket object class which was added in kernel 2.6.20.
|
|
||||||
- Patch for prelink relabefrom it's temp files from Dan Walsh.
|
|
||||||
- Patch for capability fix for auditd and networking fix for syslogd from
|
|
||||||
Dan Walsh.
|
|
||||||
- Patch to remove redundant mls_trusted_object() call from Dan Walsh.
|
|
||||||
- Patch for misc fixes to nis ypxfr policy from Dan Walsh.
|
|
||||||
- Patch to allow apmd to telinit from Dan Walsh.
|
|
||||||
- Patch for additional labeling of samba files from Stefan Schulze
|
|
||||||
Frielinghaus.
|
|
||||||
- Patch to remove incorrect cron labeling in apache.fc from Ryan Bradetich.
|
|
||||||
- Fix ptys and ttys to be device nodes.
|
|
||||||
- Fix explicit use of httpd_t in openca_domtrans().
|
|
||||||
- Clean up file context regexes in apache and java, from Eamon Walsh.
|
|
||||||
- Patches from Dan Walsh:
|
|
||||||
Thu, 25 Jan 2007
|
|
||||||
- Added modules:
|
|
||||||
consolekit (Dan Walsh)
|
|
||||||
fail2ban (Dan Walsh)
|
|
||||||
zabbix (Dan Walsh)
|
|
||||||
|
|
||||||
* Tue Dec 12 2006 Chris PeBenito <selinux@tresys.com> - 20061212
|
|
||||||
- Add policy patterns support macros. This changes the behavior of
|
|
||||||
the create_dir_perms and create_file_perms permission sets.
|
|
||||||
- Association polmatch MLS constraint making unlabeled_t an exception
|
|
||||||
is no longer needed, patch from Venkat Yekkirala.
|
|
||||||
- Context contains checking for PAM and cron from James Antill.
|
|
||||||
- Add a reload target to Modules.devel and change the load
|
|
||||||
target to only insert modules that were changed.
|
|
||||||
- Allow semanage to read from /root on strict non-MLS for
|
|
||||||
local policy modules.
|
|
||||||
- Gentoo init script fixes for udev.
|
|
||||||
- Allow udev to read kernel modules.inputmap.
|
|
||||||
- Dnsmasq fixes from testing.
|
|
||||||
- Allow kernel NFS server to getattr filesystems so df can work
|
|
||||||
on clients.
|
|
||||||
- Patch from Matt Anderson for a MLS constraint exemption on a
|
|
||||||
file that can be written to from a subject whose range is
|
|
||||||
within the object's range.
|
|
||||||
- Enhanced setransd support from Darrel Goeddel.
|
|
||||||
- Patches from Dan Walsh:
|
|
||||||
Tue, 24 Oct 2006
|
|
||||||
Wed, 29 Nov 2006
|
|
||||||
- Added modules:
|
|
||||||
aide (Matt Anderson)
|
|
||||||
ccs (Dan Walsh)
|
|
||||||
iscsi (Dan Walsh)
|
|
||||||
ricci (Dan Walsh)
|
|
||||||
|
|
||||||
* Wed Oct 18 2006 Chris PeBenito <selinux@tresys.com> - 20061018
|
|
||||||
- Patch from Russell Coker Thu, 5 Oct 2006
|
|
||||||
- Move range transitions to modules.
|
|
||||||
- Make number of MLS sensitivities, and number of MLS and MCS
|
|
||||||
categories configurable as build options.
|
|
||||||
- Add role infrastructure.
|
|
||||||
- Debian updates from Erich Schubert.
|
|
||||||
- Add nscd_socket_use() to auth_use_nsswitch().
|
|
||||||
- Remove old selopt rules.
|
|
||||||
- Full support for netfilter_contexts.
|
|
||||||
- MRTG patch for daemon operation from Stefan.
|
|
||||||
- Add authlogin interface to abstract common access for login programs.
|
|
||||||
- Remove setbool auditallow, except for RHEL4.
|
|
||||||
- Change eventpollfs to task SID labeling.
|
|
||||||
- Add key support from Michael LeMay.
|
|
||||||
- Add ftpdctl domain to ftp, from Paul Howarth.
|
|
||||||
- Fix build system to not move type declarations out of optionals.
|
|
||||||
- Add gcc-config domain to portage.
|
|
||||||
- Add packet object class and support in corenetwork.
|
|
||||||
- Add a copy of genhomedircon for monolithic policy building, so that a
|
|
||||||
policycoreutils package update is not required for RHEL4 systems.
|
|
||||||
- Add appletalk sockets for use in cups.
|
|
||||||
- Add Make target to validate module linking.
|
|
||||||
- Make duplicate template and interface declarations a fatal error.
|
|
||||||
- Patch to stabilize modules.conf `make conf` output, from Erich Schubert.
|
|
||||||
- Move xconsole_device_t from devices to xserver since it is
|
|
||||||
not actually a device, it is a named pipe.
|
|
||||||
- Handle nonexistant .fc and .if files in devel Makefile by
|
|
||||||
automatically creating empty files.
|
|
||||||
- Remove unused devfs_control_t.
|
|
||||||
- Add rhel4 distro, which also implies redhat distro.
|
|
||||||
- Remove unneeded range_transition for su_exec_t and move the
|
|
||||||
type declaration back to the su module.
|
|
||||||
- Constrain transitions in MCS so unconfined_t cannot have
|
|
||||||
arbitrary category sets.
|
|
||||||
- Change reiserfs from xattr filesystem to genfscon as it's xattrs
|
|
||||||
are currently nonfunctional.
|
|
||||||
- Change files and filesystem modules to use their own interfaces.
|
|
||||||
- Add user fonts to xserver.
|
|
||||||
- Additional interfaces in corecommands, miscfiles, and userdomain
|
|
||||||
from Joy Latten.
|
|
||||||
- Miscellaneous fixes from Thomas Bleher.
|
|
||||||
- Deprecate module name as first parameter of optional_policy()
|
|
||||||
now that optionals are allowed everywhere.
|
|
||||||
- Enable optional blocks in base module and monolithic policy.
|
|
||||||
This requires checkpolicy 1.30.1.
|
|
||||||
- Fix vpn module declaration.
|
|
||||||
- Numerous fixes from Dan Walsh.
|
|
||||||
- Change build order to preserve m4 line number information so policy
|
|
||||||
compile errors are useful again.
|
|
||||||
- Additional MLS interfaces from Chad Hanson.
|
|
||||||
- Move some rules out of domain_type() and domain_base_type()
|
|
||||||
to the TE file, to use the domain attribute to take advantage
|
|
||||||
of space savings from attribute use.
|
|
||||||
- Add global stack smashing protector rule for urandom access from
|
|
||||||
Petre Rodan.
|
|
||||||
- Fix temporary rules at the bottom of portmap.
|
|
||||||
- Updated comments in mls file from Chad Hanson.
|
|
||||||
- Patches from Dan Walsh:
|
|
||||||
Fri, 17 Mar 2006
|
|
||||||
Wed, 29 Mar 2006
|
|
||||||
Tue, 11 Apr 2006
|
|
||||||
Fri, 14 Apr 2006
|
|
||||||
Tue, 18 Apr 2006
|
|
||||||
Thu, 20 Apr 2006
|
|
||||||
Tue, 02 May 2006
|
|
||||||
Mon, 15 May 2006
|
|
||||||
Thu, 18 May 2006
|
|
||||||
Tue, 06 Jun 2006
|
|
||||||
Mon, 12 Jun 2006
|
|
||||||
Tue, 20 Jun 2006
|
|
||||||
Wed, 26 Jul 2006
|
|
||||||
Wed, 23 Aug 2006
|
|
||||||
Thu, 31 Aug 2006
|
|
||||||
Fri, 01 Sep 2006
|
|
||||||
Tue, 05 Sep 2006
|
|
||||||
Wed, 20 Sep 2006
|
|
||||||
Fri, 22 Sep 2006
|
|
||||||
Mon, 25 Sep 2006
|
|
||||||
- Added modules:
|
|
||||||
afs
|
|
||||||
amavis (Erich Schubert)
|
|
||||||
apt (Erich Schubert)
|
|
||||||
asterisk
|
|
||||||
audioentropy
|
|
||||||
authbind
|
|
||||||
backup
|
|
||||||
calamaris
|
|
||||||
cipe
|
|
||||||
clamav (Erich Schubert)
|
|
||||||
clockspeed (Petre Rodan)
|
|
||||||
courier
|
|
||||||
dante
|
|
||||||
dcc
|
|
||||||
ddclient
|
|
||||||
dpkg (Erich Schubert)
|
|
||||||
dnsmasq
|
|
||||||
ethereal
|
|
||||||
evolution
|
|
||||||
games
|
|
||||||
gatekeeper
|
|
||||||
gift
|
|
||||||
gnome (James Carter)
|
|
||||||
imaze
|
|
||||||
ircd
|
|
||||||
jabber
|
|
||||||
monop
|
|
||||||
mozilla
|
|
||||||
mplayer
|
|
||||||
munin
|
|
||||||
nagios
|
|
||||||
nessus
|
|
||||||
netlabel (Paul Moore)
|
|
||||||
nsd
|
|
||||||
ntop
|
|
||||||
nx
|
|
||||||
oav
|
|
||||||
oddjob (Dan Walsh)
|
|
||||||
openca
|
|
||||||
openvpn (Petre Rodan)
|
|
||||||
perdition
|
|
||||||
portslave
|
|
||||||
postgrey
|
|
||||||
pxe
|
|
||||||
pyzor (Dan Walsh)
|
|
||||||
qmail (Petre Rodan)
|
|
||||||
razor
|
|
||||||
resmgr
|
|
||||||
rhgb
|
|
||||||
rssh
|
|
||||||
snort
|
|
||||||
soundserver
|
|
||||||
speedtouch
|
|
||||||
sxid
|
|
||||||
thunderbird
|
|
||||||
tor (Erich Schubert)
|
|
||||||
transproxy
|
|
||||||
tripwire
|
|
||||||
uptime
|
|
||||||
uwimap
|
|
||||||
vmware
|
|
||||||
watchdog
|
|
||||||
xen (Dan Walsh)
|
|
||||||
xprint
|
|
||||||
yam
|
|
||||||
|
|
||||||
* Tue Mar 07 2006 Chris PeBenito <selinux@tresys.com> - 20060307
|
|
||||||
- Make all interface parameters required.
|
|
||||||
- Move boot_t, system_map_t, and modules_object_t to files module,
|
|
||||||
and move bootloader to admin layer.
|
|
||||||
- Add semanage policy for semodule from Dan Walsh.
|
|
||||||
- Remove allow_execmem from targeted policy domain_base_type().
|
|
||||||
- Add users_extra and seusers support.
|
|
||||||
- Postfix fixes from Serge Hallyn.
|
|
||||||
- Run python and shell directly to interpret scripts so policy
|
|
||||||
sources need not be executable.
|
|
||||||
- Add desc tag XML to booleans and tunables, and add summary
|
|
||||||
to param XML tag, to make future translations possible.
|
|
||||||
- Remove unused lvm_vg_t.
|
|
||||||
- Many interface renames to improve naming consistency.
|
|
||||||
- Merge xdm into xserver.
|
|
||||||
- Remove kernel module reversed interfaces.
|
|
||||||
- Add filename attribute to module XML tag and lineno attribute to
|
|
||||||
interface XML tag.
|
|
||||||
- Changed QUIET build option to a yes or no option.
|
|
||||||
- Add a Makefile used for compiling loadable modules in a
|
|
||||||
user's development environment, building against policy headers.
|
|
||||||
- Add Make target for installing policy headers.
|
|
||||||
- Separate per-userdomain template expansion from the userdomain
|
|
||||||
module and add infrastructure to expand templates in the modules
|
|
||||||
that own the template.
|
|
||||||
- Enable secadm only for MLS policies.
|
|
||||||
- Remove role change rules in su and sudo since this functionality has been
|
|
||||||
removed from these programs.
|
|
||||||
- Add ctags Make target from Thomas Bleher.
|
|
||||||
- Collapse commands with grep piped to sed into one sed command.
|
|
||||||
- Fix type_change bug in term_user_pty().
|
|
||||||
- Move ice_tmp_t from miscfiles to xserver.
|
|
||||||
- Login fixes from Serge Hallyn.
|
|
||||||
- Move xserver_log_t from xdm to xserver.
|
|
||||||
- Add lpr per-userdomain policy to lpd.
|
|
||||||
- Miscellaneous fixes from Dan Walsh.
|
|
||||||
- Change initrc_var_run_t interface noun from script_pid to utmp,
|
|
||||||
for greater clarity.
|
|
||||||
- Added modules:
|
|
||||||
certwatch
|
|
||||||
mono (Dan Walsh)
|
|
||||||
mrtg
|
|
||||||
portage
|
|
||||||
tvtime
|
|
||||||
userhelper
|
|
||||||
usernetctl
|
|
||||||
wine (Dan Walsh)
|
|
||||||
xserver
|
|
||||||
|
|
||||||
* Tue Jan 17 2006 Chris PeBenito <selinux@tresys.com> - 20060117
|
|
||||||
- Adds support for generating corenetwork interfaces based on attributes
|
|
||||||
in addition to types.
|
|
||||||
- Permits the listing of multiple nodes in a network_node() that will be
|
|
||||||
given the same type.
|
|
||||||
- Add two new permission sets for stream sockets.
|
|
||||||
- Rename file type transition interfaces verb from create to
|
|
||||||
filetrans to differentiate it from create interfaces without
|
|
||||||
type transitions.
|
|
||||||
- Fix expansion of interfaces from disabled modules.
|
|
||||||
- Rsync can be long running from init,
|
|
||||||
added rules to allow this.
|
|
||||||
- Add polyinstantiation build option.
|
|
||||||
- Add setcontext to the association object class.
|
|
||||||
- Add apache relay and db connect tunables.
|
|
||||||
- Rename texrel_shlib_t to textrel_shlib_t.
|
|
||||||
- Add swat to samba module.
|
|
||||||
- Numerous miscellaneous fixes from Dan Walsh.
|
|
||||||
- Added modules:
|
|
||||||
alsa
|
|
||||||
automount
|
|
||||||
cdrecord
|
|
||||||
daemontools (Petre Rodan)
|
|
||||||
ddcprobe
|
|
||||||
djbdns (Petre Rodan)
|
|
||||||
fetchmail
|
|
||||||
irc
|
|
||||||
java
|
|
||||||
lockdev
|
|
||||||
logwatch (Dan Walsh)
|
|
||||||
openct
|
|
||||||
prelink (Dan Walsh)
|
|
||||||
publicfile (Petre Rodan)
|
|
||||||
readahead
|
|
||||||
roundup
|
|
||||||
screen
|
|
||||||
slocate (Dan Walsh)
|
|
||||||
slrnpull
|
|
||||||
smartmon
|
|
||||||
sysstat
|
|
||||||
ucspitcp (Petre Rodan)
|
|
||||||
usbmodules
|
|
||||||
vbetool (Dan Walsh)
|
|
||||||
|
|
||||||
* Wed Dec 07 2005 Chris PeBenito <selinux@tresys.com> - 20051207
|
|
||||||
- Add unlabeled IPSEC association rule to domains with
|
|
||||||
networking permissions.
|
|
||||||
- Merge systemuser back in to users, as these files
|
|
||||||
do not need to be split.
|
|
||||||
- Add check for duplicate interface/template definitions.
|
|
||||||
- Move domain, files, and corecommands modules to kernel
|
|
||||||
layer to resolve some layering inconsistencies.
|
|
||||||
- Move policy build options out of Makefile into build.conf.
|
|
||||||
- Add yppasswd to nis module.
|
|
||||||
- Change optional_policy() to refer to the module name
|
|
||||||
rather than modulename.te.
|
|
||||||
- Fix labeling targets to use installed file_contexts rather
|
|
||||||
than partial file_contexts in the policy source directory.
|
|
||||||
- Fix build process to use make's internal vpath functions
|
|
||||||
to detect modules rather than using subshells and find.
|
|
||||||
- Add install target for modular policy.
|
|
||||||
- Add load target for modular policy.
|
|
||||||
- Add appconfig dependency to the load target.
|
|
||||||
- Miscellaneous fixes from Dan Walsh.
|
|
||||||
- Fix corenetwork gen_context()'s to expand during the policy
|
|
||||||
build phase instead of during the generation phase.
|
|
||||||
- Added policies:
|
|
||||||
amanda
|
|
||||||
avahi
|
|
||||||
canna
|
|
||||||
cyrus
|
|
||||||
dbskk
|
|
||||||
dovecot
|
|
||||||
distcc
|
|
||||||
i18n_input
|
|
||||||
irqbalance
|
|
||||||
lpd
|
|
||||||
networkmanager
|
|
||||||
pegasus
|
|
||||||
postfix
|
|
||||||
procmail
|
|
||||||
radius
|
|
||||||
rdisc
|
|
||||||
rpc
|
|
||||||
spamassassin
|
|
||||||
timidity
|
|
||||||
xdm
|
|
||||||
xfs
|
|
||||||
|
|
||||||
* Wed Oct 19 2005 Chris PeBenito <selinux@tresys.com> - 20051019
|
|
||||||
- Many fixes to make loadable modules build.
|
|
||||||
- Add targets for sechecker.
|
|
||||||
- Updated to sedoctool to read bool files and tunable
|
|
||||||
files separately.
|
|
||||||
- Changed the xml tag of <boolean> to <bool> to be consistent
|
|
||||||
with gen_bool().
|
|
||||||
- Modified the implementation of segenxml to use regular
|
|
||||||
expressions.
|
|
||||||
- Rename context_template() to gen_context() to clarify
|
|
||||||
that its not a Reference Policy template, but a support
|
|
||||||
macro.
|
|
||||||
- Add disable_*_trans bool support for targeted policy.
|
|
||||||
- Add MLS module to handle MLS constraint exceptions,
|
|
||||||
such as reading up and writing down.
|
|
||||||
- Fix errors uncovered by sediff.
|
|
||||||
- Added policies:
|
|
||||||
anaconda
|
|
||||||
apache
|
|
||||||
apm
|
|
||||||
arpwatch
|
|
||||||
bluetooth
|
|
||||||
dmidecode
|
|
||||||
finger
|
|
||||||
ftp
|
|
||||||
kudzu
|
|
||||||
mailman
|
|
||||||
ppp
|
|
||||||
radvd
|
|
||||||
sasl
|
|
||||||
webalizer
|
|
||||||
|
|
||||||
* Thu Sep 22 2005 Chris PeBenito <selinux@tresys.com> - 20050922
|
|
||||||
- Make logrotate, sendmail, sshd, and rpm policies
|
|
||||||
unconfined in the targeted policy so no special
|
|
||||||
modules.conf is required.
|
|
||||||
- Add experimental MCS support.
|
|
||||||
- Add appconfig for MLS.
|
|
||||||
- Add equivalents for old can_resolve(), can_ldap(), and
|
|
||||||
can_portmap() to sysnetwork.
|
|
||||||
- Fix base module compile issues.
|
|
||||||
- Added policies:
|
|
||||||
cpucontrol
|
|
||||||
cvs
|
|
||||||
ktalk
|
|
||||||
portmap
|
|
||||||
postgresql
|
|
||||||
rlogin
|
|
||||||
samba
|
|
||||||
snmp
|
|
||||||
stunnel
|
|
||||||
telnet
|
|
||||||
tftp
|
|
||||||
uucp
|
|
||||||
vpn
|
|
||||||
zebra
|
|
||||||
|
|
||||||
* Wed Sep 07 2005 Chris PeBenito <selinux@tresys.com> - 20050907
|
|
||||||
- Fix errors uncovered by sediff.
|
|
||||||
- Doc tool will explicitly say a module does not have interfaces
|
|
||||||
or templates on the module page.
|
|
||||||
- Added policies:
|
|
||||||
comsat
|
|
||||||
dbus
|
|
||||||
dhcp
|
|
||||||
dictd
|
|
||||||
hal
|
|
||||||
inn
|
|
||||||
ntp
|
|
||||||
squid
|
|
||||||
|
|
||||||
* Fri Aug 26 2005 Chris PeBenito <selinux@tresys.com> - 20050826
|
|
||||||
- Add Makefile support for building loadable modules.
|
|
||||||
- Add genclassperms.py tool to add require blocks
|
|
||||||
for loadable modules.
|
|
||||||
- Change sedoctool to make required modules part of base
|
|
||||||
by default, otherwise make as modules, in modules.conf.
|
|
||||||
- Fix segenxml to handle modules with no interfaces.
|
|
||||||
- Rename ipsec connect interface for consistency.
|
|
||||||
- Add missing parts of unix stream socket connect interface
|
|
||||||
of ipsec.
|
|
||||||
- Rename inetd connect interface for consistency.
|
|
||||||
- Rename interface for purging contents of tmp, for clarity,
|
|
||||||
since it allows deletion of classes other than file.
|
|
||||||
- Misc. cleanups.
|
|
||||||
- Added policies:
|
|
||||||
acct
|
|
||||||
bind
|
|
||||||
firstboot
|
|
||||||
gpm
|
|
||||||
howl
|
|
||||||
ldap
|
|
||||||
loadkeys
|
|
||||||
mysql
|
|
||||||
privoxy
|
|
||||||
quota
|
|
||||||
rshd
|
|
||||||
rsync
|
|
||||||
su
|
|
||||||
sudo
|
|
||||||
tcpd
|
|
||||||
tmpreaper
|
|
||||||
updfstab
|
|
||||||
|
|
||||||
* Tue Aug 2 2005 Chris PeBenito <selinux@tresys.com> - 20050802
|
|
||||||
- Fix comparison bug in fc_sort.
|
|
||||||
- Fix handling of ordered and unordered HTML lists.
|
|
||||||
- Corenetwork now supports multiple network interfaces having the
|
|
||||||
same type.
|
|
||||||
- Doc tool now creates pages for global Booleans and global tunables.
|
|
||||||
- Doc tool now links directly to the interface/template in the
|
|
||||||
module page when it is selected in the interface/template index.
|
|
||||||
- Added support for layer summaries.
|
|
||||||
- Added policies:
|
|
||||||
ipsec
|
|
||||||
nscd
|
|
||||||
pcmcia
|
|
||||||
raid
|
|
||||||
|
|
||||||
* Thu Jul 7 2005 Chris PeBenito <selinux@tresys.com> - 20050707
|
|
||||||
- Changed xml to have modules encapsulated by layer tags, rather
|
|
||||||
than putting layer="foo" in the module tags. Also in the future
|
|
||||||
we can put a summary and description for each layer.
|
|
||||||
- Added tool to infer interface, module, and layer tags. This will
|
|
||||||
now list all interfaces, even if they are missing xml docs.
|
|
||||||
- Shortened xml tag names.
|
|
||||||
- Added macros to declare interfaces and templates.
|
|
||||||
- Added interface call trace.
|
|
||||||
- Updated all xml documentation for shorter and inferred tags.
|
|
||||||
- Doc tool now displays templates in the web pages.
|
|
||||||
- Doc tool retains the user's settings in modules.conf and
|
|
||||||
tunables.conf if the files already exist.
|
|
||||||
- Modules.conf behavior has been changed to be a list of all
|
|
||||||
available modules, and the user can specify if the module is
|
|
||||||
built as a loadable module, included in the monolithic policy,
|
|
||||||
or excluded.
|
|
||||||
- Added policies:
|
|
||||||
fstools (fsck, mkfs, swapon, etc. tools)
|
|
||||||
logrotate
|
|
||||||
inetd
|
|
||||||
kerberos
|
|
||||||
nis (ypbind and ypserv)
|
|
||||||
ssh (server, client, and agent)
|
|
||||||
unconfined
|
|
||||||
- Added infrastructure for targeted policy support, only missing
|
|
||||||
transition boolean support.
|
|
||||||
|
|
||||||
* Wed Jun 15 2005 Chris PeBenito <selinux@tresys.com> - 20050615
|
|
||||||
- Initial release
|
|
48
INSTALL
48
INSTALL
@ -1,48 +0,0 @@
|
|||||||
Reference Policy has a requirement of checkpolicy 1.33.1 and
|
|
||||||
libsepol-1.16.2. Red Hat Enterprise Linux 4 and Fedora Core 4 RPMs
|
|
||||||
are available on the CLIP download page at http://oss.tresys.com,
|
|
||||||
and can be installed thusly:
|
|
||||||
|
|
||||||
Red Hat Enterprise Linux 4:
|
|
||||||
|
|
||||||
rpm -i libsepol-1.11.7-1.i386.rpm
|
|
||||||
rpm -U checkpolicy-1.28-4.i386.rpm
|
|
||||||
|
|
||||||
Fedora Core 4:
|
|
||||||
|
|
||||||
rpm -U libsepol-1.11.7-1.i386.rpm checkpolicy-1.28-4.i386.rpm
|
|
||||||
|
|
||||||
To install Reference Policy sources into /etc/selinux/refpolicy/src/policy:
|
|
||||||
|
|
||||||
make install-src
|
|
||||||
|
|
||||||
This will back up a pre-existing source policy to the
|
|
||||||
/etc/selinux/refpolicy/src/policy.bak directory.
|
|
||||||
|
|
||||||
If you do not have a modules.conf, one can be generated:
|
|
||||||
|
|
||||||
make conf
|
|
||||||
|
|
||||||
This will create a default modules.conf. Options for the policy
|
|
||||||
build process can be found in build.conf. After installing the policy sources,
|
|
||||||
the old Make targets have been maintained for the monolithic policy:
|
|
||||||
|
|
||||||
Local policy development:
|
|
||||||
|
|
||||||
make policy
|
|
||||||
|
|
||||||
Compile and install the policy:
|
|
||||||
|
|
||||||
make install
|
|
||||||
|
|
||||||
Compile, install, and load the policy:
|
|
||||||
|
|
||||||
make load
|
|
||||||
|
|
||||||
Filesystem labeling:
|
|
||||||
|
|
||||||
make relabel
|
|
||||||
make checklabels
|
|
||||||
make restorelabels
|
|
||||||
|
|
||||||
See the README for more information on available make targets.
|
|
269
README
269
README
@ -1,269 +0,0 @@
|
|||||||
1) Reference Policy make targets:
|
|
||||||
|
|
||||||
General Make targets:
|
|
||||||
|
|
||||||
install-src Install the policy sources into
|
|
||||||
/etc/selinux/NAME/src/policy, where NAME is defined in
|
|
||||||
the Makefile. If not defined, the TYPE, as defined in
|
|
||||||
the Makefile, is used. The default NAME is refpolicy.
|
|
||||||
A pre-existing source policy will be moved to
|
|
||||||
/etc/selinux/NAME/src/policy.bak.
|
|
||||||
|
|
||||||
conf Regenerate policy.xml, and update/create modules.conf
|
|
||||||
and booleans.conf. This should be done after adding
|
|
||||||
or removing modules, or after running the bare target.
|
|
||||||
If the configuration files exist, their settings will
|
|
||||||
be preserved. This must be ran on policy sources that
|
|
||||||
are checked out from the CVS repository before they can
|
|
||||||
be used.
|
|
||||||
|
|
||||||
clean Delete all temporary files, compiled policies,
|
|
||||||
and file_contexts. Configuration files are left intact.
|
|
||||||
|
|
||||||
bare Do the clean make target and also delete configuration
|
|
||||||
files, web page documentation, and policy.xml.
|
|
||||||
|
|
||||||
html Regenerate policy.xml and create web page documentation
|
|
||||||
in the doc/html directory.
|
|
||||||
|
|
||||||
Make targets specific to modular (loadable modules) policies:
|
|
||||||
|
|
||||||
base Compile and package the base module. This is the
|
|
||||||
default target for modular policies.
|
|
||||||
|
|
||||||
modules Compile and package all Reference Policy modules
|
|
||||||
configured to be built as loadable modules.
|
|
||||||
|
|
||||||
MODULENAME.pp Compile and package the MODULENAME Reference Policy
|
|
||||||
module.
|
|
||||||
|
|
||||||
all Compile and package the base module and all Reference
|
|
||||||
Policy modules configured to be built as loadable
|
|
||||||
modules.
|
|
||||||
|
|
||||||
install Compile, package, and install the base module and
|
|
||||||
Reference Policy modules configured to be built as
|
|
||||||
loadable modules.
|
|
||||||
|
|
||||||
load Compile, package, and install the base module and
|
|
||||||
Reference Policy modules configured to be built as
|
|
||||||
loadable modules, then insert them into the module
|
|
||||||
store.
|
|
||||||
|
|
||||||
validate Validate if the configured modules can successfully
|
|
||||||
link and expand.
|
|
||||||
|
|
||||||
install-headers Install the policy headers into /usr/share/selinux/NAME.
|
|
||||||
The headers are sufficient for building a policy
|
|
||||||
module locally, without requiring the complete
|
|
||||||
Reference Policy sources. The build.conf settings
|
|
||||||
for this policy configuration should be set before
|
|
||||||
using this target.
|
|
||||||
|
|
||||||
Make targets specific to monolithic policies:
|
|
||||||
|
|
||||||
policy Compile a policy locally for development and testing.
|
|
||||||
This is the default target for monolithic policies.
|
|
||||||
|
|
||||||
install Compile and install the policy and file contexts.
|
|
||||||
|
|
||||||
load Compile and install the policy and file contexts, then
|
|
||||||
load the policy.
|
|
||||||
|
|
||||||
enableaudit Remove all dontaudit rules from policy.conf.
|
|
||||||
|
|
||||||
relabel Relabel the filesystem.
|
|
||||||
|
|
||||||
checklabels Check the labels on the filesystem, and report when
|
|
||||||
a file would be relabeled, but do not change its label.
|
|
||||||
|
|
||||||
restorelabels Relabel the filesystem and report each file that is
|
|
||||||
relabeled.
|
|
||||||
|
|
||||||
|
|
||||||
2) Reference Policy Build Options (build.conf)
|
|
||||||
|
|
||||||
TYPE String. Available options are standard, mls, and mcs.
|
|
||||||
For a type enforcement only system, set standard.
|
|
||||||
This optionally enables multi-level security (MLS) or
|
|
||||||
multi-category security (MCS) features. This option
|
|
||||||
controls enable_mls, and enable_mcs policy blocks.
|
|
||||||
|
|
||||||
NAME String (optional). Sets the name of the policy; the
|
|
||||||
NAME is used when installing files to e.g.,
|
|
||||||
/etc/selinux/NAME and /usr/share/selinux/NAME. If not
|
|
||||||
set, the policy type (TYPE) is used.
|
|
||||||
|
|
||||||
DISTRO String (optional). Enable distribution-specific policy.
|
|
||||||
Available options are redhat, rhel4, gentoo, debian,
|
|
||||||
and suse. This option controls distro_redhat,
|
|
||||||
distro_rhel4, distro_gentoo, distro_debian, and
|
|
||||||
distro_suse policy blocks.
|
|
||||||
|
|
||||||
MONOLITHIC Boolean. If set, a monolithic policy is built,
|
|
||||||
otherwise a modular policy is built.
|
|
||||||
|
|
||||||
DIRECT_INITRC Boolean. If set, sysadm will be allowed to directly
|
|
||||||
run init scripts, instead of requiring the run_init
|
|
||||||
tool. This is a build option instead of a tunable since
|
|
||||||
role transitions do not work in conditional policy.
|
|
||||||
This option controls direct_sysadm_daemon policy
|
|
||||||
blocks.
|
|
||||||
|
|
||||||
OUTPUT_POLICY Integer. Set the version of the policy created when
|
|
||||||
building a monolithic policy. This option has no effect
|
|
||||||
on modular policy.
|
|
||||||
|
|
||||||
UNK_PERMS String. Set the kernel behavior for handling of
|
|
||||||
permissions defined in the kernel but missing from the
|
|
||||||
policy. The permissions can either be allowed, denied,
|
|
||||||
or the policy loading can be rejected.
|
|
||||||
|
|
||||||
UBAC Boolean. If set, the SELinux user will be used
|
|
||||||
additionally for approximate role separation.
|
|
||||||
|
|
||||||
MLS_SENS Integer. Set the number of sensitivities in the MLS
|
|
||||||
policy. Ignored on standard and MCS policies.
|
|
||||||
|
|
||||||
MLS_CATS Integer. Set the number of categories in the MLS
|
|
||||||
policy. Ignored on standard and MCS policies.
|
|
||||||
|
|
||||||
MCS_CATS Integer. Set the number of categories in the MCS
|
|
||||||
policy. Ignored on standard and MLS policies.
|
|
||||||
|
|
||||||
QUIET Boolean. If set, the build system will only display
|
|
||||||
status messages and error messages. This option has no
|
|
||||||
effect on policy.
|
|
||||||
|
|
||||||
|
|
||||||
3) Reference Policy Files and Directories
|
|
||||||
All directories relative to the root of the Reference Policy sources directory.
|
|
||||||
|
|
||||||
Makefile General rules for building the policy.
|
|
||||||
|
|
||||||
Rules.modular Makefile rules specific to building loadable module
|
|
||||||
policies.
|
|
||||||
|
|
||||||
Rules.monolithic Makefile rules specific to building monolithic policies.
|
|
||||||
|
|
||||||
build.conf Options which influence the building of the policy,
|
|
||||||
such as the policy type and distribution.
|
|
||||||
|
|
||||||
config/appconfig-* Application configuration files for all configurations
|
|
||||||
of the Reference Policy (targeted/strict with or without
|
|
||||||
MLS or MCS). These are used by SELinux-aware programs.
|
|
||||||
|
|
||||||
config/local.users The file read by load policy for adding SELinux users
|
|
||||||
to the policy on the fly.
|
|
||||||
|
|
||||||
doc/html/* This contains the contents of the in-policy XML
|
|
||||||
documentation, presented in web page form.
|
|
||||||
|
|
||||||
doc/policy.dtd The doc/policy.xml file is validated against this DTD.
|
|
||||||
|
|
||||||
doc/policy.xml This file is generated/updated by the conf and html make
|
|
||||||
targets. It contains the complete XML documentation
|
|
||||||
included in the policy.
|
|
||||||
|
|
||||||
doc/templates/* Templates used for documentation web pages.
|
|
||||||
|
|
||||||
policy/booleans.conf This file is generated/updated by the conf make target.
|
|
||||||
It contains the booleans in the policy, and their
|
|
||||||
default values. If tunables are implemented as
|
|
||||||
booleans, tunables will also be included. This file
|
|
||||||
will be installed as the /etc/selinux/NAME/booleans
|
|
||||||
file.
|
|
||||||
|
|
||||||
policy/constraints This file defines additional constraints on permissions
|
|
||||||
in the form of boolean expressions that must be
|
|
||||||
satisfied in order for specified permissions to be
|
|
||||||
granted. These constraints are used to further refine
|
|
||||||
the type enforcement rules and the role allow rules.
|
|
||||||
Typically, these constraints are used to restrict
|
|
||||||
changes in user identity or role to certain domains.
|
|
||||||
|
|
||||||
policy/global_booleans This file defines all booleans that have a global scope,
|
|
||||||
their default value, and documentation.
|
|
||||||
|
|
||||||
policy/global_tunables This file defines all tunables that have a global scope,
|
|
||||||
their default value, and documentation.
|
|
||||||
|
|
||||||
policy/flask/initial_sids This file has declarations for each initial SID.
|
|
||||||
|
|
||||||
policy/flask/security_classes This file has declarations for each security class.
|
|
||||||
|
|
||||||
policy/flask/access_vectors This file defines the access vectors. Common
|
|
||||||
prefixes for access vectors may be defined at the
|
|
||||||
beginning of the file. After the common prefixes are
|
|
||||||
defined, an access vector may be defined for each
|
|
||||||
security class.
|
|
||||||
|
|
||||||
policy/mcs The multi-category security (MCS) configuration.
|
|
||||||
|
|
||||||
policy/mls The multi-level security (MLS) configuration.
|
|
||||||
|
|
||||||
policy/modules/* Each directory represents a layer in Reference Policy
|
|
||||||
all of the modules are contained in one of these layers.
|
|
||||||
|
|
||||||
policy/modules.conf This file contains a listing of available modules, and
|
|
||||||
how they will be used when building Reference Policy. To
|
|
||||||
prevent a module from being used, set the module to
|
|
||||||
"off". For monolithic policies, modules set to "base"
|
|
||||||
and "module" will be included in the policy. For
|
|
||||||
modular policies, modules set to "base" will be included
|
|
||||||
in the base module; those set to "module" will be
|
|
||||||
compiled as individual loadable modules.
|
|
||||||
|
|
||||||
policy/rolemap This file contains prefix and user domain type that
|
|
||||||
corresponds to each user role. The contents of this
|
|
||||||
file will be used to expand the per-user domain
|
|
||||||
templates for each module.
|
|
||||||
|
|
||||||
policy/support/* Support macros.
|
|
||||||
|
|
||||||
policy/users This file defines the users included in the policy.
|
|
||||||
|
|
||||||
support/* Tools used in the build process.
|
|
||||||
|
|
||||||
|
|
||||||
4) Building policy modules using Reference Policy headers:
|
|
||||||
|
|
||||||
The system must first have the Reference Policy headers installed, typically
|
|
||||||
by the distribution. Otherwise, the headers can be installed using the
|
|
||||||
install-headers target from the full Reference Policy sources.
|
|
||||||
|
|
||||||
To set up a directory to build a local module, one must simply place a .te
|
|
||||||
file in a directory. A sample Makefile to use in the directory is the
|
|
||||||
Makefile.example in the doc directory. This may be installed in
|
|
||||||
/usr/share/doc, under the directory for the distribution's policy.
|
|
||||||
Alternatively, the primary Makefile in the headers directory (typically
|
|
||||||
/usr/share/selinux/NAME/Makefile) can be called directly, using make's -f
|
|
||||||
option.
|
|
||||||
|
|
||||||
Larger projects can set up a structure of layers, just as in Reference
|
|
||||||
Policy, by creating policy/modules/LAYERNAME directories. Each layer also
|
|
||||||
must have a metadata.xml file which is an XML file with a summary tag and
|
|
||||||
optional desc (long description) tag. This should describe the purpose of
|
|
||||||
the layer.
|
|
||||||
|
|
||||||
Metadata.xml example:
|
|
||||||
|
|
||||||
<summary>ABC modules for the XYZ components.</summary>
|
|
||||||
|
|
||||||
Make targets for modules built from headers:
|
|
||||||
|
|
||||||
MODULENAME.pp Compile and package the MODULENAME local module.
|
|
||||||
|
|
||||||
all Compile and package the modules in the current
|
|
||||||
directory.
|
|
||||||
|
|
||||||
load Compile and package the modules in the current
|
|
||||||
directory, then insert them into the module store.
|
|
||||||
|
|
||||||
refresh Attempts to reinsert all modules that are currently
|
|
||||||
in the module store from the local and system module
|
|
||||||
packages.
|
|
||||||
|
|
||||||
xml Build a policy.xml from the XML included with the
|
|
||||||
base policy headers and any XML in the modules in
|
|
||||||
the current directory.
|
|
@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
AWK ?= gawk
|
|
||||||
|
|
||||||
NAME ?= $(shell $(AWK) -F= '/^SELINUXTYPE/{ print $$2 }' /etc/selinux/config)
|
|
||||||
SHAREDIR ?= /usr/share/selinux
|
|
||||||
HEADERDIR := $(SHAREDIR)/$(NAME)/include
|
|
||||||
|
|
||||||
include $(HEADERDIR)/Makefile
|
|
@ -1,6 +0,0 @@
|
|||||||
# myapp executable will have:
|
|
||||||
# label: system_u:object_r:myapp_exec_t
|
|
||||||
# MLS sensitivity: s0
|
|
||||||
# MCS categories: <none>
|
|
||||||
|
|
||||||
/usr/sbin/myapp -- gen_context(system_u:object_r:myapp_exec_t,s0)
|
|
@ -1,54 +0,0 @@
|
|||||||
## <summary>Myapp example policy</summary>
|
|
||||||
## <desc>
|
|
||||||
## <p>
|
|
||||||
## More descriptive text about myapp. The desc
|
|
||||||
## tag can also use p, ul, and ol
|
|
||||||
## html tags for formatting.
|
|
||||||
## </p>
|
|
||||||
## <p>
|
|
||||||
## This policy supports the following myapp features:
|
|
||||||
## <ul>
|
|
||||||
## <li>Feature A</li>
|
|
||||||
## <li>Feature B</li>
|
|
||||||
## <li>Feature C</li>
|
|
||||||
## </ul>
|
|
||||||
## </p>
|
|
||||||
## </desc>
|
|
||||||
#
|
|
||||||
|
|
||||||
########################################
|
|
||||||
## <summary>
|
|
||||||
## Execute a domain transition to run myapp.
|
|
||||||
## </summary>
|
|
||||||
## <param name="domain">
|
|
||||||
## <summary>
|
|
||||||
## Domain allowed to transition.
|
|
||||||
## </summary>
|
|
||||||
## </param>
|
|
||||||
#
|
|
||||||
interface(`myapp_domtrans',`
|
|
||||||
gen_require(`
|
|
||||||
type myapp_t, myapp_exec_t;
|
|
||||||
')
|
|
||||||
|
|
||||||
domtrans_pattern($1,myapp_exec_t,myapp_t)
|
|
||||||
')
|
|
||||||
|
|
||||||
########################################
|
|
||||||
## <summary>
|
|
||||||
## Read myapp log files.
|
|
||||||
## </summary>
|
|
||||||
## <param name="domain">
|
|
||||||
## <summary>
|
|
||||||
## Domain allowed to read the log files.
|
|
||||||
## </summary>
|
|
||||||
## </param>
|
|
||||||
#
|
|
||||||
interface(`myapp_read_log',`
|
|
||||||
gen_require(`
|
|
||||||
type myapp_log_t;
|
|
||||||
')
|
|
||||||
|
|
||||||
logging_search_logs($1)
|
|
||||||
allow $1 myapp_log_t:file read_file_perms;
|
|
||||||
')
|
|
@ -1,28 +0,0 @@
|
|||||||
|
|
||||||
policy_module(myapp,1.0.0)
|
|
||||||
|
|
||||||
########################################
|
|
||||||
#
|
|
||||||
# Declarations
|
|
||||||
#
|
|
||||||
|
|
||||||
type myapp_t;
|
|
||||||
type myapp_exec_t;
|
|
||||||
domain_type(myapp_t)
|
|
||||||
domain_entry_file(myapp_t, myapp_exec_t)
|
|
||||||
|
|
||||||
type myapp_log_t;
|
|
||||||
logging_log_file(myapp_log_t)
|
|
||||||
|
|
||||||
type myapp_tmp_t;
|
|
||||||
files_tmp_file(myapp_tmp_t)
|
|
||||||
|
|
||||||
########################################
|
|
||||||
#
|
|
||||||
# Myapp local policy
|
|
||||||
#
|
|
||||||
|
|
||||||
allow myapp_t myapp_log_t:file { read_file_perms append_file_perms };
|
|
||||||
|
|
||||||
allow myapp_t myapp_tmp_t:file manage_file_perms;
|
|
||||||
files_tmp_filetrans(myapp_t,myapp_tmp_t,file)
|
|
@ -1,44 +0,0 @@
|
|||||||
<!ENTITY % inline.class "pre|p|ul|ol|li">
|
|
||||||
|
|
||||||
<!ELEMENT policy (layer+,(tunable|bool)*)>
|
|
||||||
<!ELEMENT layer (summary,module+)>
|
|
||||||
<!ATTLIST layer
|
|
||||||
name CDATA #REQUIRED>
|
|
||||||
<!ELEMENT module (summary,desc?,required?,(interface|template)*,(bool|tunable)*)>
|
|
||||||
<!ATTLIST module
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
filename CDATA #REQUIRED>
|
|
||||||
<!ELEMENT required (#PCDATA)>
|
|
||||||
<!ATTLIST required
|
|
||||||
val (true|false) "false">
|
|
||||||
<!ELEMENT tunable (desc)>
|
|
||||||
<!ATTLIST tunable
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
dftval CDATA #REQUIRED>
|
|
||||||
<!ELEMENT bool (desc)>
|
|
||||||
<!ATTLIST bool
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
dftval CDATA #REQUIRED>
|
|
||||||
<!ELEMENT summary (#PCDATA)>
|
|
||||||
<!ELEMENT interface (summary,desc?,param+,infoflow?,(rolebase|rolecap)?)>
|
|
||||||
<!ATTLIST interface name CDATA #REQUIRED lineno CDATA #REQUIRED>
|
|
||||||
<!ELEMENT template (summary,desc?,param+,(rolebase|rolecap)?)>
|
|
||||||
<!ATTLIST template name CDATA #REQUIRED lineno CDATA #REQUIRED>
|
|
||||||
<!ELEMENT desc (#PCDATA|%inline.class;)*>
|
|
||||||
<!ELEMENT param (summary)>
|
|
||||||
<!ATTLIST param
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
optional (true|false) "false"
|
|
||||||
unused (true|false) "false">
|
|
||||||
<!ELEMENT infoflow EMPTY>
|
|
||||||
<!ATTLIST infoflow
|
|
||||||
type CDATA #REQUIRED
|
|
||||||
weight CDATA #IMPLIED>
|
|
||||||
<!ELEMENT rolebase EMPTY>
|
|
||||||
<!ELEMENT rolecap EMPTY>
|
|
||||||
|
|
||||||
<!ATTLIST pre caption CDATA #IMPLIED>
|
|
||||||
<!ELEMENT p (#PCDATA|%inline.class;)*>
|
|
||||||
<!ELEMENT ul (li+)>
|
|
||||||
<!ELEMENT ol (li+)>
|
|
||||||
<!ELEMENT li (#PCDATA|%inline.class;)*>
|
|
23
doc/templates/bool_list.html
vendored
23
doc/templates/bool_list.html
vendored
@ -1,23 +0,0 @@
|
|||||||
<h3>Master boolean index:</h3>
|
|
||||||
|
|
||||||
[[for bool in booleans]]
|
|
||||||
<div id="interfacesmall">
|
|
||||||
[[if bool.has_key('mod_layer')]]
|
|
||||||
Module: <a href='[[bool['mod_layer']+ "_" + bool['mod_name'] + ".html#link_" + bool['bool_name']]]'>
|
|
||||||
[[bool['mod_name']]]</a><p/>
|
|
||||||
Layer: <a href='[[bool['mod_layer']]].html'>
|
|
||||||
[[bool['mod_layer']]]</a><p/>
|
|
||||||
[[else]]
|
|
||||||
Global
|
|
||||||
[[end]]
|
|
||||||
<div id="codeblock">
|
|
||||||
[[bool['bool_name']]]
|
|
||||||
<small>(Default: [[bool['def_val']]])</small>
|
|
||||||
</div>
|
|
||||||
[[if bool['desc']]]
|
|
||||||
<div id="description">
|
|
||||||
[[bool['desc']]]
|
|
||||||
</div>
|
|
||||||
[[end]]
|
|
||||||
</div>
|
|
||||||
[[end]]
|
|
13
doc/templates/boolean.html
vendored
13
doc/templates/boolean.html
vendored
@ -1,13 +0,0 @@
|
|||||||
[[for bool in booleans]]
|
|
||||||
<a name="link_[[bool['bool_name']]]"></a>
|
|
||||||
<div id="interface">
|
|
||||||
<div id="codeblock">[[bool['bool_name']]]</div>
|
|
||||||
<div id="description">
|
|
||||||
<h5>Default value</h5>
|
|
||||||
<p>[[bool['def_val']]]</p>
|
|
||||||
[[if bool['desc']]]
|
|
||||||
<h5>Description</h5>
|
|
||||||
[[bool['desc']]]
|
|
||||||
[[end]]
|
|
||||||
</div></div>
|
|
||||||
[[end]]
|
|
14
doc/templates/global_bool_list.html
vendored
14
doc/templates/global_bool_list.html
vendored
@ -1,14 +0,0 @@
|
|||||||
<h3>Global booleans:</h3>
|
|
||||||
|
|
||||||
[[for bool in booleans]]
|
|
||||||
<div id="interface">
|
|
||||||
<div id="codeblock">[[bool['bool_name']]]</div>
|
|
||||||
<div id="description">
|
|
||||||
<h5>Default value</h5>
|
|
||||||
<p>[[bool['def_val']]]</p>
|
|
||||||
[[if bool['desc']]]
|
|
||||||
<h5>Description</h5>
|
|
||||||
[[bool['desc']]]
|
|
||||||
[[end]]
|
|
||||||
</div></div>
|
|
||||||
[[end]]
|
|
14
doc/templates/global_tun_list.html
vendored
14
doc/templates/global_tun_list.html
vendored
@ -1,14 +0,0 @@
|
|||||||
<h3>Global tunables:</h3>
|
|
||||||
|
|
||||||
[[for tun in tunables]]
|
|
||||||
<div id="interface">
|
|
||||||
<div id="codeblock">[[tun['tun_name']]]</div>
|
|
||||||
<div id="description">
|
|
||||||
<h5>Default value</h5>
|
|
||||||
<p>[[tun['def_val']]]</p>
|
|
||||||
[[if tun['desc']]]
|
|
||||||
<h5>Description</h5>
|
|
||||||
[[tun['desc']]]
|
|
||||||
[[end]]
|
|
||||||
</div></div>
|
|
||||||
[[end]]
|
|
15
doc/templates/header.html
vendored
15
doc/templates/header.html
vendored
@ -1,15 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Security Enhanced Linux Reference Policy
|
|
||||||
</title>
|
|
||||||
<style type="text/css" media="all">@import "style.css";</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="Header">Security Enhanced Linux Reference Policy</div>
|
|
||||||
[[menu]]
|
|
||||||
<div id="Content">
|
|
||||||
[[content]]
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
33
doc/templates/int_list.html
vendored
33
doc/templates/int_list.html
vendored
@ -1,33 +0,0 @@
|
|||||||
<h3>Master interface index:</h3>
|
|
||||||
|
|
||||||
[[for int in interfaces]]
|
|
||||||
<div id="interfacesmall">
|
|
||||||
Module: <a href='[[int['mod_layer']+ "_" + int['mod_name'] + ".html#link_" + int['interface_name']]]'>
|
|
||||||
[[int['mod_name']]]</a><p/>
|
|
||||||
Layer: <a href='[[int['mod_layer']]].html'>
|
|
||||||
[[int['mod_layer']]]</a><p/>
|
|
||||||
<div id="codeblock">
|
|
||||||
[[exec i = 0]]
|
|
||||||
<b>[[int['interface_name']]]</b>(
|
|
||||||
[[for arg in int['interface_parameters']]]
|
|
||||||
[[if i != 0]]
|
|
||||||
,
|
|
||||||
[[end]]
|
|
||||||
[[exec i = 1]]
|
|
||||||
[[if arg['optional'] == 'yes']]
|
|
||||||
[
|
|
||||||
[[end]]
|
|
||||||
[[arg['name']]]
|
|
||||||
[[if arg['optional'] == 'yes']]
|
|
||||||
]
|
|
||||||
[[end]]
|
|
||||||
[[end]]
|
|
||||||
)<br>
|
|
||||||
</div>
|
|
||||||
[[if int['interface_summary']]]
|
|
||||||
<div id="description">
|
|
||||||
[[int['interface_summary']]]
|
|
||||||
</div>
|
|
||||||
[[end]]
|
|
||||||
</div>
|
|
||||||
[[end]]
|
|
50
doc/templates/interface.html
vendored
50
doc/templates/interface.html
vendored
@ -1,50 +0,0 @@
|
|||||||
[[for int in interfaces]]
|
|
||||||
<a name="link_[[int['interface_name']]]"></a>
|
|
||||||
<div id="interface">
|
|
||||||
[[if int.has_key("mod_layer")]]
|
|
||||||
Layer: [[mod_layer]]<br>
|
|
||||||
[[end]]
|
|
||||||
[[if int.has_key("mod_name")]]
|
|
||||||
Module: [[mod_name]]<br>
|
|
||||||
[[end]]
|
|
||||||
<div id="codeblock">
|
|
||||||
[[exec i = 0]]
|
|
||||||
<b>[[int['interface_name']]]</b>(
|
|
||||||
[[for arg in int['interface_parameters']]]
|
|
||||||
[[if i != 0]]
|
|
||||||
,
|
|
||||||
[[end]]
|
|
||||||
[[exec i = 1]]
|
|
||||||
[[if arg['optional'] == 'yes']]
|
|
||||||
[
|
|
||||||
[[end]]
|
|
||||||
[[arg['name']]]
|
|
||||||
[[if arg['optional'] == 'yes']]
|
|
||||||
]
|
|
||||||
[[end]]
|
|
||||||
[[end]]
|
|
||||||
)<br>
|
|
||||||
</div>
|
|
||||||
<div id="description">
|
|
||||||
[[if int['interface_summary']]]
|
|
||||||
<h5>Summary</h5>
|
|
||||||
[[int['interface_summary']]]
|
|
||||||
[[end]]
|
|
||||||
[[if int['interface_desc']]]
|
|
||||||
<h5>Description</h5>
|
|
||||||
[[int['interface_desc']]]
|
|
||||||
[[end]]
|
|
||||||
<h5>Parameters</h5>
|
|
||||||
<table border="1" cellspacing="0" cellpadding="3" width="65%">
|
|
||||||
<tr><th >Parameter:</th><th >Description:</th></tr>
|
|
||||||
[[for arg in int['interface_parameters']]]
|
|
||||||
<tr><td>
|
|
||||||
[[arg['name']]]
|
|
||||||
</td><td>
|
|
||||||
[[arg['desc']]]
|
|
||||||
</td></tr>
|
|
||||||
[[end]]
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
[[end]]
|
|
26
doc/templates/menu.html
vendored
26
doc/templates/menu.html
vendored
@ -1,26 +0,0 @@
|
|||||||
<div id='Menu'>
|
|
||||||
[[for layer_name, layer_mods in menulist]]
|
|
||||||
<a href="[[layer_name]].html">+
|
|
||||||
[[layer_name]]</a></br/>
|
|
||||||
<div id='subitem'>
|
|
||||||
[[for module, s in layer_mods]]
|
|
||||||
- <a href='[[layer_name + "_" + module]].html'>
|
|
||||||
[[module]]</a><br/>
|
|
||||||
[[end]]
|
|
||||||
</div>
|
|
||||||
[[end]]
|
|
||||||
<br/><p/>
|
|
||||||
<a href="global_booleans.html">* Global Booleans </a>
|
|
||||||
<br/><p/>
|
|
||||||
<a href="global_tunables.html">* Global Tunables </a>
|
|
||||||
<p/><br/><p/>
|
|
||||||
<a href="index.html">* Layer Index</a>
|
|
||||||
<br/><p/>
|
|
||||||
<a href="booleans.html">* Boolean Index</a>
|
|
||||||
<br/><p/>
|
|
||||||
<a href="tunables.html">* Tunable Index</a>
|
|
||||||
<br/><p/>
|
|
||||||
<a href="interfaces.html">* Interface Index</a>
|
|
||||||
<br/><p/>
|
|
||||||
<a href="templates.html">* Template Index</a>
|
|
||||||
</div>
|
|
52
doc/templates/module.html
vendored
52
doc/templates/module.html
vendored
@ -1,52 +0,0 @@
|
|||||||
<a name="top":></a>
|
|
||||||
<h1>Layer: [[mod_layer]]</h1><p/>
|
|
||||||
<h2>Module: [[mod_name]]</h2><p/>
|
|
||||||
[[if booleans]]
|
|
||||||
<a href=#booleans>Booleans</a>
|
|
||||||
[[end]]
|
|
||||||
[[if tunables]]
|
|
||||||
<a href=#tunables>Tunables</a>
|
|
||||||
[[end]]
|
|
||||||
[[if interfaces]]
|
|
||||||
<a href=#interfaces>Interfaces</a>
|
|
||||||
[[end]]
|
|
||||||
[[if templates]]
|
|
||||||
<a href=#templates>Templates</a>
|
|
||||||
[[end]]
|
|
||||||
<h3>Description:</h3>
|
|
||||||
[[if mod_desc]]
|
|
||||||
<p>[[mod_desc]]</p>
|
|
||||||
[[else]]
|
|
||||||
<p>[[mod_summary]]</p>
|
|
||||||
[[end]]
|
|
||||||
[[if mod_req]]
|
|
||||||
<p>This module is required to be included in all policies.</p>
|
|
||||||
[[end]]
|
|
||||||
<hr>
|
|
||||||
[[if booleans]]
|
|
||||||
<a name="booleans"></a>
|
|
||||||
<h3>Booleans: </h3>
|
|
||||||
[[booleans]]
|
|
||||||
<a href=#top>Return</a>
|
|
||||||
[[end]]
|
|
||||||
[[if tunables]]
|
|
||||||
<a name="tunables"></a>
|
|
||||||
<h3>Tunables: </h3>
|
|
||||||
[[tunables]]
|
|
||||||
<a href=#top>Return</a>
|
|
||||||
[[end]]
|
|
||||||
[[if interfaces]]
|
|
||||||
<a name="interfaces"></a>
|
|
||||||
<h3>Interfaces: </h3>
|
|
||||||
[[interfaces]]
|
|
||||||
<a href=#top>Return</a>
|
|
||||||
[[end]]
|
|
||||||
[[if templates]]
|
|
||||||
<a name="templates"></a>
|
|
||||||
<h3>Templates: </h3>
|
|
||||||
[[templates]]
|
|
||||||
<a href=#top>Return</a>
|
|
||||||
[[end]]
|
|
||||||
[[if not templates and not interfaces and not tunables]]
|
|
||||||
<h3>No booleans, tunables, interfaces, or templates.</h3>
|
|
||||||
[[end]]
|
|
19
doc/templates/module_list.html
vendored
19
doc/templates/module_list.html
vendored
@ -1,19 +0,0 @@
|
|||||||
[[if mod_layer]]
|
|
||||||
<h1>Layer: [[mod_layer]]</h1><p/>
|
|
||||||
[[if layer_summary]]
|
|
||||||
<p>[[layer_summary]]</p><br/>
|
|
||||||
[[end]]
|
|
||||||
[[end]]
|
|
||||||
<table border="1" cellspacing="0" cellpadding="3" width="75%">
|
|
||||||
<tr><td class="title">Module:</td><td class="title">Description:</td></tr>
|
|
||||||
[[for layer_name, layer_mods in menulist]]
|
|
||||||
[[for module, s in layer_mods]]
|
|
||||||
<tr><td>
|
|
||||||
<a href='[[layer_name + "_" + module]].html'>
|
|
||||||
[[module]]</a></td>
|
|
||||||
<td>[[s]]</td>
|
|
||||||
[[end]]
|
|
||||||
</td></tr>
|
|
||||||
[[end]]
|
|
||||||
</table>
|
|
||||||
<p/><br/><br/>
|
|
216
doc/templates/style.css
vendored
216
doc/templates/style.css
vendored
@ -1,216 +0,0 @@
|
|||||||
body {
|
|
||||||
margin:0px;
|
|
||||||
padding:0px;
|
|
||||||
font-family:verdana, arial, helvetica, sans-serif;
|
|
||||||
color:#333;
|
|
||||||
background-color:white;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
margin:0px 0px 5px 0px;
|
|
||||||
padding:0px;
|
|
||||||
font-size:150%
|
|
||||||
line-height:28px;
|
|
||||||
font-weight:900;
|
|
||||||
color:#ccc;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
font-size:125%;
|
|
||||||
margin:0px;
|
|
||||||
padding:5px 0px 10px 0px;
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
font-size:110%;
|
|
||||||
margin:0px;
|
|
||||||
padding:5px 0px 10px 5px;
|
|
||||||
}
|
|
||||||
h4 {
|
|
||||||
font-size:100%;
|
|
||||||
margin:0px;
|
|
||||||
padding:5px 0px 10px 5px;
|
|
||||||
}
|
|
||||||
h5 {
|
|
||||||
font-size:100%;
|
|
||||||
margin:0px;
|
|
||||||
font-weight:600;
|
|
||||||
padding:0px 0px 5px 0px;
|
|
||||||
margin:0px 0px 0px 5px;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
font:11px/20px verdana, arial, helvetica, sans-serif;
|
|
||||||
margin:0px 0px 0px 10px;
|
|
||||||
padding:0px;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
/* normal */
|
|
||||||
font:11px/20px verdana, arial, helvetica, sans-serif;
|
|
||||||
margin:0px 0px 0px 10px;
|
|
||||||
padding:0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
tt {
|
|
||||||
/* inline code */
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
background-color:#efefef;
|
|
||||||
/*background-color: white;*/
|
|
||||||
border-style:solid;
|
|
||||||
border-color:black;
|
|
||||||
border-width:0px 1px 1px 0px;
|
|
||||||
color: black;
|
|
||||||
text-align: left;
|
|
||||||
font:11px/20px verdana, arial, helvetica, sans-serif;
|
|
||||||
margin-left: 5%;
|
|
||||||
margin-right: 5%;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
font-weight:500;
|
|
||||||
background-color: #eaeaef;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
td.header {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
#Content>p {margin:0px;}
|
|
||||||
#Content>p+p {text-indent:30px;}
|
|
||||||
a {
|
|
||||||
color:#09c;
|
|
||||||
font-size:11px;
|
|
||||||
text-decoration:none;
|
|
||||||
font-weight:600;
|
|
||||||
font-family:verdana, arial, helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
a:link {color:#09c;}
|
|
||||||
a:visited {color:#07a;}
|
|
||||||
a:hover {background-color:#eee;}
|
|
||||||
|
|
||||||
#Codeblock {
|
|
||||||
margin:5px 50px 5px 10px;
|
|
||||||
padding:5px 0px 5px 15px;
|
|
||||||
border-style:solid;
|
|
||||||
border-color:lightgrey;
|
|
||||||
border-width:1px 1px 1px 1px;
|
|
||||||
background-color:#f5f5ff;
|
|
||||||
font-size:100%;
|
|
||||||
font-weight:600;
|
|
||||||
text-decoration:none;
|
|
||||||
font-family:monospace;
|
|
||||||
}
|
|
||||||
#Interface {
|
|
||||||
margin:5px 0px 25px 5px;
|
|
||||||
padding:5px 0px 5px 5px;
|
|
||||||
border-style:solid;
|
|
||||||
border-color:black;
|
|
||||||
border-width:1px 1px 1px 1px;
|
|
||||||
background-color:#fafafa;
|
|
||||||
font-size:14px;
|
|
||||||
font-weight:400;
|
|
||||||
text-decoration:none;
|
|
||||||
font-family:verdana, arial, helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
#Interfacesmall {
|
|
||||||
margin:0px 0px 5px 0px;
|
|
||||||
padding:5px 0px 0px 5px;
|
|
||||||
border-style:solid;
|
|
||||||
border-color:black;
|
|
||||||
border-width:1px 1px 1px 1px;
|
|
||||||
background-color:#fafafa;
|
|
||||||
font-size:14px;
|
|
||||||
font-weight:400;
|
|
||||||
text-decoration:none;
|
|
||||||
font-family:verdana, arial, helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
#Template {
|
|
||||||
margin:5px 0px 25px 5px;
|
|
||||||
padding:5px 0px 5px 5px;
|
|
||||||
border-style:solid;
|
|
||||||
border-color:black;
|
|
||||||
border-width:1px 1px 1px 1px;
|
|
||||||
background-color:#fafafa;
|
|
||||||
font-size:14px;
|
|
||||||
font-weight:400;
|
|
||||||
text-decoration:none;
|
|
||||||
font-family:verdana, arial, helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
#Templatesmall {
|
|
||||||
margin:0px 0px 5px 0px;
|
|
||||||
padding:5px 0px 0px 5px;
|
|
||||||
border-style:solid;
|
|
||||||
border-color:black;
|
|
||||||
border-width:1px 1px 1px 1px;
|
|
||||||
background-color:#fafafa;
|
|
||||||
font-size:14px;
|
|
||||||
font-weight:400;
|
|
||||||
text-decoration:none;
|
|
||||||
font-family:verdana, arial, helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
#Description {
|
|
||||||
margin:0px 0px 0px 5px;
|
|
||||||
padding:0px 0px 0px 5px;
|
|
||||||
text-decoration:none;
|
|
||||||
font-family:verdana, arial, helvetica, sans-serif;
|
|
||||||
font-size:12px;
|
|
||||||
font-weight:400;
|
|
||||||
}
|
|
||||||
pre {
|
|
||||||
margin:0px;
|
|
||||||
padding:0px;
|
|
||||||
font-size:14px;
|
|
||||||
text-decoration:none;
|
|
||||||
font-family:verdana, arial, helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
dl {
|
|
||||||
/* definition text block */
|
|
||||||
font:11px/20px verdana, arial, helvetica, sans-serif;
|
|
||||||
margin:0px 0px 16px 0px;
|
|
||||||
padding:0px;
|
|
||||||
}
|
|
||||||
dt {
|
|
||||||
/* definition term */
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
#Header {
|
|
||||||
margin:50px 0px 10px 0px;
|
|
||||||
padding:17px 0px 0px 20px;
|
|
||||||
/* For IE5/Win's benefit height = [correct height] + [top padding] + [top and bottom border widths] */
|
|
||||||
height:33px; /* 14px + 17px + 2px = 33px */
|
|
||||||
border-style:solid;
|
|
||||||
border-color:black;
|
|
||||||
border-width:1px 0px; /* top and bottom borders: 1px; left and right borders: 0px */
|
|
||||||
line-height:11px;
|
|
||||||
font-size:110%;
|
|
||||||
background-color:#eee;
|
|
||||||
voice-family: "\"}\"";
|
|
||||||
voice-family:inherit;
|
|
||||||
height:14px; /* the correct height */
|
|
||||||
}
|
|
||||||
body>#Header {height:14px;}
|
|
||||||
#Content {
|
|
||||||
margin:0px 50px 0px 200px;
|
|
||||||
padding:10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#Menu {
|
|
||||||
position:absolute;
|
|
||||||
top:100px;
|
|
||||||
left:20px;
|
|
||||||
width:162px;
|
|
||||||
padding:10px;
|
|
||||||
background-color:#eee;
|
|
||||||
border:1px solid #aaa;
|
|
||||||
line-height:17px;
|
|
||||||
text-align:left;
|
|
||||||
voice-family: "\"}\"";
|
|
||||||
voice-family:inherit;
|
|
||||||
width:160px;
|
|
||||||
}
|
|
||||||
#Menu subitem {
|
|
||||||
font-size: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body>#Menu {width:160px;}
|
|
33
doc/templates/temp_list.html
vendored
33
doc/templates/temp_list.html
vendored
@ -1,33 +0,0 @@
|
|||||||
<h3>Master template index:</h3>
|
|
||||||
|
|
||||||
[[for temp in templates]]
|
|
||||||
<div id="templatesmall">
|
|
||||||
Module: <a href='[[temp['mod_layer']+ "_" + temp['mod_name'] + ".html#link_" + temp['template_name']]]'>
|
|
||||||
[[temp['mod_name']]]</a><p/>
|
|
||||||
Layer: <a href='[[temp['mod_layer']]].html'>
|
|
||||||
[[temp['mod_layer']]]</a><p/>
|
|
||||||
<div id="codeblock">
|
|
||||||
[[exec i = 0]]
|
|
||||||
<b>[[temp['template_name']]]</b>(
|
|
||||||
[[for arg in temp['template_parameters']]]
|
|
||||||
[[if i != 0]]
|
|
||||||
,
|
|
||||||
[[end]]
|
|
||||||
[[exec i = 1]]
|
|
||||||
[[if arg['optional'] == 'yes']]
|
|
||||||
[
|
|
||||||
[[end]]
|
|
||||||
[[arg['name']]]
|
|
||||||
[[if arg['optional'] == 'yes']]
|
|
||||||
]
|
|
||||||
[[end]]
|
|
||||||
[[end]]
|
|
||||||
)<br>
|
|
||||||
</div>
|
|
||||||
[[if temp['template_summary']]]
|
|
||||||
<div id="description">
|
|
||||||
[[temp['template_summary']]]
|
|
||||||
</div>
|
|
||||||
[[end]]
|
|
||||||
</div>
|
|
||||||
[[end]]
|
|
50
doc/templates/template.html
vendored
50
doc/templates/template.html
vendored
@ -1,50 +0,0 @@
|
|||||||
[[for temp in templates]]
|
|
||||||
<a name="link_[[temp['template_name']]]"></a>
|
|
||||||
<div id="template">
|
|
||||||
[[if temp.has_key("mod_layer")]]
|
|
||||||
Layer: [[mod_layer]]<br>
|
|
||||||
[[end]]
|
|
||||||
[[if temp.has_key("mod_name")]]
|
|
||||||
Module: [[mod_name]]<br>
|
|
||||||
[[end]]
|
|
||||||
<div id="codeblock">
|
|
||||||
[[exec i = 0]]
|
|
||||||
<b>[[temp['template_name']]]</b>(
|
|
||||||
[[for arg in temp['template_parameters']]]
|
|
||||||
[[if i != 0]]
|
|
||||||
,
|
|
||||||
[[end]]
|
|
||||||
[[exec i = 1]]
|
|
||||||
[[if arg['optional'] == 'yes']]
|
|
||||||
[
|
|
||||||
[[end]]
|
|
||||||
[[arg['name']]]
|
|
||||||
[[if arg['optional'] == 'yes']]
|
|
||||||
]
|
|
||||||
[[end]]
|
|
||||||
[[end]]
|
|
||||||
)<br>
|
|
||||||
</div>
|
|
||||||
<div id="description">
|
|
||||||
[[if temp['template_summary']]]
|
|
||||||
<h5>Summary</h5>
|
|
||||||
[[temp['template_summary']]]
|
|
||||||
[[end]]
|
|
||||||
[[if temp['template_desc']]]
|
|
||||||
<h5>Description</h5>
|
|
||||||
[[temp['template_desc']]]
|
|
||||||
[[end]]
|
|
||||||
<h5>Parameters</h5>
|
|
||||||
<table border="1" cellspacing="0" cellpadding="3" width="65%">
|
|
||||||
<tr><th >Parameter:</th><th >Description:</th></tr>
|
|
||||||
[[for arg in temp['template_parameters']]]
|
|
||||||
<tr><td>
|
|
||||||
[[arg['name']]]
|
|
||||||
</td><td>
|
|
||||||
[[arg['desc']]]
|
|
||||||
</td></tr>
|
|
||||||
[[end]]
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
[[end]]
|
|
23
doc/templates/tun_list.html
vendored
23
doc/templates/tun_list.html
vendored
@ -1,23 +0,0 @@
|
|||||||
<h3>Master tunable index:</h3>
|
|
||||||
|
|
||||||
[[for tun in tunables]]
|
|
||||||
<div id="interfacesmall">
|
|
||||||
[[if tun.has_key('mod_layer')]]
|
|
||||||
Module: <a href='[[tun['mod_layer']+ "_" + tun['mod_name'] + ".html#link_" + tun['tun_name']]]'>
|
|
||||||
[[tun['mod_name']]]</a><p/>
|
|
||||||
Layer: <a href='[[tun['mod_layer']]].html'>
|
|
||||||
[[tun['mod_layer']]]</a><p/>
|
|
||||||
[[else]]
|
|
||||||
Global
|
|
||||||
[[end]]
|
|
||||||
<div id="codeblock">
|
|
||||||
[[tun['tun_name']]]
|
|
||||||
<small>(Default: [[tun['def_val']]])</small>
|
|
||||||
</div>
|
|
||||||
[[if tun['desc']]]
|
|
||||||
<div id="description">
|
|
||||||
[[tun['desc']]]
|
|
||||||
</div>
|
|
||||||
[[end]]
|
|
||||||
</div>
|
|
||||||
[[end]]
|
|
13
doc/templates/tunable.html
vendored
13
doc/templates/tunable.html
vendored
@ -1,13 +0,0 @@
|
|||||||
[[for tun in tunables]]
|
|
||||||
<a name="link_[[tun['tun_name']]]"></a>
|
|
||||||
<div id="interface">
|
|
||||||
<div id="codeblock">[[tun['tun_name']]]</div>
|
|
||||||
<div id="description">
|
|
||||||
<h5>Default value</h5>
|
|
||||||
<p>[[tun['def_val']]]</p>
|
|
||||||
[[if tun['desc']]]
|
|
||||||
<h5>Description</h5>
|
|
||||||
[[tun['desc']]]
|
|
||||||
[[end]]
|
|
||||||
</div></div>
|
|
||||||
[[end]]
|
|
28
exclude
28
exclude
@ -1,28 +0,0 @@
|
|||||||
CVS
|
|
||||||
*2004*
|
|
||||||
*h
|
|
||||||
*~
|
|
||||||
.#*
|
|
||||||
*.spec
|
|
||||||
*.orig
|
|
||||||
*.rej
|
|
||||||
*.suse
|
|
||||||
*.strict
|
|
||||||
policy.conf
|
|
||||||
policy.15
|
|
||||||
tmp
|
|
||||||
debian
|
|
||||||
#*
|
|
||||||
policy.conf
|
|
||||||
policy.xml
|
|
||||||
modules.conf
|
|
||||||
booleans.conf
|
|
||||||
base.conf
|
|
||||||
base.fc
|
|
||||||
*.pyc
|
|
||||||
fc_sort
|
|
||||||
CVS
|
|
||||||
CVSROOT
|
|
||||||
.svn
|
|
||||||
svn
|
|
||||||
.git
|
|
2048
modules-mls.conf
2048
modules-mls.conf
File diff suppressed because it is too large
Load Diff
@ -1,3 +0,0 @@
|
|||||||
system_u:system_u:s0-s15:c0.c1023
|
|
||||||
root:root:s0-s15:c0.c1023
|
|
||||||
__default__:user_u:s0
|
|
@ -1,3 +0,0 @@
|
|||||||
root:root:s0-s0:c0.c1023
|
|
||||||
system_u:system_u:s0-s0:c0.c1023
|
|
||||||
__default__:user_u:s0
|
|
@ -1,255 +0,0 @@
|
|||||||
|
|
||||||
# helper tools
|
|
||||||
AWK ?= gawk
|
|
||||||
INSTALL ?= install
|
|
||||||
M4 ?= m4
|
|
||||||
SED ?= sed
|
|
||||||
EINFO ?= echo
|
|
||||||
PYTHON ?= python
|
|
||||||
CUT ?= cut
|
|
||||||
|
|
||||||
NAME ?= $(shell $(AWK) -F= '/^SELINUXTYPE/{ print $$2 }' /etc/selinux/config)
|
|
||||||
SHAREDIR ?= /usr/share/selinux
|
|
||||||
HEADERDIR ?= $(SHAREDIR)/$(NAME)/include
|
|
||||||
|
|
||||||
include $(HEADERDIR)/build.conf
|
|
||||||
|
|
||||||
# executables
|
|
||||||
PREFIX := /usr
|
|
||||||
BINDIR := $(PREFIX)/bin
|
|
||||||
SBINDIR := $(PREFIX)/sbin
|
|
||||||
CHECKMODULE := $(BINDIR)/checkmodule
|
|
||||||
SEMODULE := $(SBINDIR)/semodule
|
|
||||||
SEMOD_PKG := $(BINDIR)/semodule_package
|
|
||||||
XMLLINT := $(BINDIR)/xmllint
|
|
||||||
|
|
||||||
# set default build options if missing
|
|
||||||
TYPE ?= standard
|
|
||||||
DIRECT_INITRC ?= n
|
|
||||||
POLY ?= n
|
|
||||||
QUIET ?= y
|
|
||||||
|
|
||||||
genxml := $(PYTHON) $(HEADERDIR)/support/segenxml.py
|
|
||||||
|
|
||||||
docs := doc
|
|
||||||
polxml := $(docs)/policy.xml
|
|
||||||
xmldtd := $(HEADERDIR)/support/policy.dtd
|
|
||||||
metaxml := metadata.xml
|
|
||||||
|
|
||||||
globaltun = $(HEADERDIR)/global_tunables.xml
|
|
||||||
globalbool = $(HEADERDIR)/global_booleans.xml
|
|
||||||
|
|
||||||
# enable MLS if requested.
|
|
||||||
ifeq "$(TYPE)" "mls"
|
|
||||||
M4PARAM += -D enable_mls
|
|
||||||
CHECKPOLICY += -M
|
|
||||||
CHECKMODULE += -M
|
|
||||||
endif
|
|
||||||
|
|
||||||
# enable MLS if MCS requested.
|
|
||||||
ifeq "$(TYPE)" "mcs"
|
|
||||||
M4PARAM += -D enable_mcs
|
|
||||||
CHECKPOLICY += -M
|
|
||||||
CHECKMODULE += -M
|
|
||||||
endif
|
|
||||||
|
|
||||||
# enable distribution-specific policy
|
|
||||||
ifneq ($(DISTRO),)
|
|
||||||
M4PARAM += -D distro_$(DISTRO)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DIRECT_INITRC),y)
|
|
||||||
M4PARAM += -D direct_sysadm_daemon
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(UBAC)" "y"
|
|
||||||
M4PARAM += -D enable_ubac
|
|
||||||
endif
|
|
||||||
|
|
||||||
# default MLS/MCS sensitivity and category settings.
|
|
||||||
MLS_SENS ?= 16
|
|
||||||
MLS_CATS ?= 1024
|
|
||||||
MCS_CATS ?= 1024
|
|
||||||
|
|
||||||
ifeq ($(QUIET),y)
|
|
||||||
verbose := @
|
|
||||||
endif
|
|
||||||
|
|
||||||
M4PARAM += -D hide_broken_symptoms -D mls_num_sens=$(MLS_SENS) -D mls_num_cats=$(MLS_CATS) -D mcs_num_cats=$(MCS_CATS)
|
|
||||||
|
|
||||||
# policy headers
|
|
||||||
m4support = $(wildcard $(HEADERDIR)/support/*.spt)
|
|
||||||
|
|
||||||
header_layers := $(filter-out $(HEADERDIR)/support,$(shell find $(wildcard $(HEADERDIR)/*) -maxdepth 0 -type d))
|
|
||||||
header_xml := $(addsuffix .xml,$(header_layers))
|
|
||||||
header_interfaces := $(foreach layer,$(header_layers),$(wildcard $(layer)/*.if))
|
|
||||||
|
|
||||||
rolemap := $(HEADERDIR)/rolemap
|
|
||||||
|
|
||||||
local_layers := $(filter-out CVS tmp $(docs),$(shell find $(wildcard *) -maxdepth 0 -type d))
|
|
||||||
local_xml := $(addprefix tmp/, $(addsuffix .xml,$(local_layers)))
|
|
||||||
|
|
||||||
all_layer_names := $(sort $(notdir $(header_layers) $(local_layers)))
|
|
||||||
|
|
||||||
3rd_party_mods := $(wildcard *.te)
|
|
||||||
detected_mods := $(3rd_party_mods) $(foreach layer,$(local_layers),$(wildcard $(layer)/*.te))
|
|
||||||
|
|
||||||
detected_ifs := $(detected_mods:.te=.if)
|
|
||||||
detected_fcs := $(detected_mods:.te=.fc)
|
|
||||||
all_packages := $(notdir $(detected_mods:.te=.pp))
|
|
||||||
|
|
||||||
# figure out what modules we may want to reload
|
|
||||||
loaded_mods = $(addsuffix .pp,$(shell $(SEMODULE) -l | $(CUT) -f1))
|
|
||||||
sys_mods = $(wildcard $(SHAREDIR)/$(NAME)/*.pp)
|
|
||||||
match_sys = $(filter $(addprefix $(SHAREDIR)/$(NAME)/,$(loaded_mods)),$(sys_mods))
|
|
||||||
match_loc = $(filter $(all_packages),$(loaded_mods))
|
|
||||||
|
|
||||||
vpath %.te $(local_layers)
|
|
||||||
vpath %.if $(local_layers)
|
|
||||||
vpath %.fc $(local_layers)
|
|
||||||
|
|
||||||
########################################
|
|
||||||
#
|
|
||||||
# Functions
|
|
||||||
#
|
|
||||||
|
|
||||||
# parse-rolemap-compat modulename,outputfile
|
|
||||||
define parse-rolemap-compat
|
|
||||||
$(verbose) $(M4) $(M4PARAM) $(rolemap) | \
|
|
||||||
$(AWK) '/^[[:blank:]]*[A-Za-z]/{ print "gen_require(type " $$3 "; role " $$1 ";)\n$1_per_userdomain_template(" $$2 "," $$3 "," $$1 ")" }' >> $2
|
|
||||||
endef
|
|
||||||
|
|
||||||
# parse-rolemap modulename,outputfile
|
|
||||||
define parse-rolemap
|
|
||||||
$(verbose) $(M4) $(M4PARAM) $(rolemap) | \
|
|
||||||
$(AWK) '/^[[:blank:]]*[A-Za-z]/{ print "gen_require(type " $$3 "; role " $$1 ";)\n$1_per_role_template(" $$2 "," $$3 "," $$1 ")" }' >> $2
|
|
||||||
endef
|
|
||||||
|
|
||||||
# peruser-expansion modulename,outputfile
|
|
||||||
define peruser-expansion
|
|
||||||
$(verbose) echo "ifdef(\`""$1""_per_role_template',\`" > $2
|
|
||||||
$(call parse-rolemap,$1,$2)
|
|
||||||
$(verbose) echo "')" >> $2
|
|
||||||
|
|
||||||
$(verbose) echo "ifdef(\`""$1""_per_userdomain_template',\`" >> $2
|
|
||||||
$(verbose) echo "errprint(\`Warning: per_userdomain_templates have been renamed to per_role_templates (""$1""_per_userdomain_template)'__endline__)" >> $2
|
|
||||||
$(call parse-rolemap-compat,$1,$2)
|
|
||||||
$(verbose) echo "')" >> $2
|
|
||||||
endef
|
|
||||||
|
|
||||||
.PHONY: clean all xml load reload
|
|
||||||
.SUFFIXES:
|
|
||||||
.SUFFIXES: .pp
|
|
||||||
# broken in make 3.81:
|
|
||||||
#.SECONDARY:
|
|
||||||
|
|
||||||
########################################
|
|
||||||
#
|
|
||||||
# Main targets
|
|
||||||
#
|
|
||||||
|
|
||||||
all: $(all_packages)
|
|
||||||
|
|
||||||
xml: $(polxml)
|
|
||||||
|
|
||||||
########################################
|
|
||||||
#
|
|
||||||
# Attempt to reinstall all installed packages
|
|
||||||
#
|
|
||||||
refresh:
|
|
||||||
@$(EINFO) "Refreshing $(NAME) modules"
|
|
||||||
$(verbose) $(SEMODULE) -b $(SHAREDIR)/$(NAME)/base.pp $(foreach mod,$(match_sys) $(match_loc),-i $(mod))
|
|
||||||
|
|
||||||
########################################
|
|
||||||
#
|
|
||||||
# Load module packages
|
|
||||||
#
|
|
||||||
|
|
||||||
load: tmp/loaded
|
|
||||||
tmp/loaded: $(all_packages)
|
|
||||||
@$(EINFO) "Loading $(NAME) modules: $(basename $(notdir $?))"
|
|
||||||
$(verbose) $(SEMODULE) $(foreach mod,$?,-i $(mod))
|
|
||||||
@mkdir -p tmp
|
|
||||||
@touch tmp/loaded
|
|
||||||
|
|
||||||
reload: $(all_packages)
|
|
||||||
@$(EINFO) "Loading $(NAME) modules: $(basename $(notdir $^))"
|
|
||||||
$(verbose) $(SEMODULE) $(foreach mod,$^,-i $(mod))
|
|
||||||
@mkdir -p tmp
|
|
||||||
@touch tmp/loaded
|
|
||||||
|
|
||||||
########################################
|
|
||||||
#
|
|
||||||
# Build module packages
|
|
||||||
#
|
|
||||||
tmp/%.mod: $(m4support) tmp/all_interfaces.conf %.te
|
|
||||||
@$(EINFO) "Compiling $(NAME) $(basename $(@F)) module"
|
|
||||||
@test -d $(@D) || mkdir -p $(@D)
|
|
||||||
$(call peruser-expansion,$(basename $(@F)),$@.role)
|
|
||||||
$(verbose) $(M4) $(M4PARAM) -s $^ $@.role > $(@:.mod=.tmp)
|
|
||||||
$(verbose) $(CHECKMODULE) -m $(@:.mod=.tmp) -o $@
|
|
||||||
|
|
||||||
tmp/%.mod.fc: $(m4support) %.fc
|
|
||||||
$(verbose) $(M4) $(M4PARAM) $^ > $@
|
|
||||||
|
|
||||||
%.pp: tmp/%.mod tmp/%.mod.fc
|
|
||||||
@echo "Creating $(NAME) $(@F) policy package"
|
|
||||||
$(verbose) $(SEMOD_PKG) -o $@ -m $< -f $<.fc
|
|
||||||
|
|
||||||
tmp/all_interfaces.conf: $(m4support) $(header_interfaces) $(detected_ifs)
|
|
||||||
@test -d $(@D) || mkdir -p $(@D)
|
|
||||||
@echo "ifdef(\`__if_error',\`m4exit(1)')" > tmp/iferror.m4
|
|
||||||
@echo "divert(-1)" > $@
|
|
||||||
$(verbose) $(M4) $^ tmp/iferror.m4 | sed -e s/dollarsstar/\$$\*/g >> $@
|
|
||||||
@echo "divert" >> $@
|
|
||||||
|
|
||||||
# so users dont have to make empty .fc and .if files
|
|
||||||
$(detected_fcs):
|
|
||||||
@touch $@
|
|
||||||
|
|
||||||
$(detected_ifs):
|
|
||||||
@echo "## <summary>$(basename $(@D))</summary>" > $@
|
|
||||||
|
|
||||||
########################################
|
|
||||||
#
|
|
||||||
# Documentation generation
|
|
||||||
#
|
|
||||||
tmp/%.xml: %/*.te %/*.if
|
|
||||||
@test -d $(@D) || mkdir -p $(@D)
|
|
||||||
$(verbose) test -f $(HEADERDIR)/$*.xml || cat $*/$(metaxml) > $@
|
|
||||||
$(verbose) $(genxml) -w -m $(sort $(basename $^)) >> $@
|
|
||||||
|
|
||||||
vars: $(local_xml)
|
|
||||||
|
|
||||||
$(polxml): $(header_xml) $(local_xml) $(globaltun) $(globalbool) $(detected_mods) $(detected_ifs)
|
|
||||||
@echo "Creating $(@F)"
|
|
||||||
@test -d $(@D) || mkdir -p $(@D)
|
|
||||||
$(verbose) echo '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>' > $@
|
|
||||||
$(verbose) echo '<!DOCTYPE policy SYSTEM "$(notdir $(xmldtd))">' >> $@
|
|
||||||
$(verbose) echo '<policy>' >> $@
|
|
||||||
$(verbose) for i in $(all_layer_names); do \
|
|
||||||
echo "<layer name=\"$$i\">" >> $@ ;\
|
|
||||||
test -f $(HEADERDIR)/$$i.xml && cat $(HEADERDIR)/$$i.xml >> $@ ;\
|
|
||||||
test -f tmp/$$i.xml && cat tmp/$$i.xml >> $@ ;\
|
|
||||||
echo "</layer>" >> $@ ;\
|
|
||||||
done
|
|
||||||
ifneq "$(strip $(3rd_party_mods))" ""
|
|
||||||
$(verbose) echo "<layer name=\"third_party\">" >> $@
|
|
||||||
$(verbose) echo "<summary>These are all third-party modules.</summary>" >> $@
|
|
||||||
$(verbose) $(genxml) -w -m $(addprefix ./,$(basename $(3rd_party_mods))) >> $@
|
|
||||||
$(verbose) echo "</layer>" >> $@
|
|
||||||
endif
|
|
||||||
$(verbose) cat $(globaltun) $(globalbool) >> $@
|
|
||||||
$(verbose) echo '</policy>' >> $@
|
|
||||||
$(verbose) if test -x $(XMLLINT) && test -f $(xmldtd); then \
|
|
||||||
$(XMLLINT) --noout --path $(dir $(xmldtd)) --dtdvalid $(xmldtd) $@ ;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
########################################
|
|
||||||
#
|
|
||||||
# Clean the environment
|
|
||||||
#
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -fR tmp
|
|
||||||
rm -f *.pp
|
|
@ -1,14 +0,0 @@
|
|||||||
# comment out lines that are moved by the build
|
|
||||||
# process, so line numbers provided by m4 are preserved.
|
|
||||||
|
|
||||||
# lines in require and optional blocks are not moved
|
|
||||||
/require \{/,/} # end require/b nextline
|
|
||||||
/optional \{/,/} # end optional/b nextline
|
|
||||||
|
|
||||||
/^[[:blank:]]*(attribute|type(alias)?) /s/^/# this line was moved by the build process: &/
|
|
||||||
/^[[:blank:]]*(port|node|netif|genfs)con /s/^/# this line was moved by the build process: &/
|
|
||||||
/^[[:blank:]]*fs_use_(xattr|task|trans) /s/^/# this line was moved by the build process: &/
|
|
||||||
/^[[:blank:]]*sid /s/^/# this line was moved by the build process: &/
|
|
||||||
/^[[:blank:]]*bool /s/^/# this line was moved by the build process: &/
|
|
||||||
|
|
||||||
:nextline
|
|
@ -1 +0,0 @@
|
|||||||
divert(`-1')
|
|
@ -1,558 +0,0 @@
|
|||||||
/* Copyright 2005, Tresys Technology
|
|
||||||
*
|
|
||||||
* Some parts of this came from matchpathcon.c in libselinux
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* PURPOSE OF THIS PROGRAM
|
|
||||||
* The original setfiles sorting algorithm did not take into
|
|
||||||
* account regular expression specificity. With the current
|
|
||||||
* strict and targeted policies this is not an issue because
|
|
||||||
* the file contexts are partially hand sorted and concatenated
|
|
||||||
* in the right order so that the matches are generally correct.
|
|
||||||
* The way reference policy and loadable policy modules handle
|
|
||||||
* file contexts makes them come out in an unpredictable order
|
|
||||||
* and therefore setfiles (or this standalone tool) need to sort
|
|
||||||
* the regular expressions in a deterministic and stable way.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BUF_SIZE 4096;
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
typedef unsigned char bool_t;
|
|
||||||
|
|
||||||
/* file_context_node
|
|
||||||
* A node used in a linked list of file contexts.c
|
|
||||||
* Each node contains the regular expression, the type and
|
|
||||||
* the context, as well as information about the regular
|
|
||||||
* expression. The regular expression data (meta, stem_len
|
|
||||||
* and str_len) can be filled in by using the fc_fill_data
|
|
||||||
* function after the regular expression has been loaded.
|
|
||||||
* next points to the next node in the linked list.
|
|
||||||
*/
|
|
||||||
typedef struct file_context_node {
|
|
||||||
char *path;
|
|
||||||
char *file_type;
|
|
||||||
char *context;
|
|
||||||
bool_t meta;
|
|
||||||
int stem_len;
|
|
||||||
int str_len;
|
|
||||||
struct file_context_node *next;
|
|
||||||
} file_context_node_t;
|
|
||||||
|
|
||||||
void file_context_node_destroy(file_context_node_t *x)
|
|
||||||
{
|
|
||||||
free(x->path);
|
|
||||||
free(x->file_type);
|
|
||||||
free(x->context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* file_context_bucket
|
|
||||||
* A node used in a linked list of buckets that contain
|
|
||||||
* file_context_node's.
|
|
||||||
* Each node contains a pointer to a file_context_node which
|
|
||||||
* is the header of its linked list. This linked list is the
|
|
||||||
* content of this bucket.
|
|
||||||
* next points to the next bucket in the linked list.
|
|
||||||
*/
|
|
||||||
typedef struct file_context_bucket {
|
|
||||||
file_context_node_t *data;
|
|
||||||
struct file_context_bucket *next;
|
|
||||||
} file_context_bucket_t;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* fc_compare
|
|
||||||
* Compares two file contexts' regular expressions and returns:
|
|
||||||
* -1 if a is less specific than b
|
|
||||||
* 0 if a and be are equally specific
|
|
||||||
* 1 if a is more specific than b
|
|
||||||
* The comparison is based on the following statements,
|
|
||||||
* in order from most important to least important, given a and b:
|
|
||||||
* If a is a regular expression and b is not,
|
|
||||||
* -> a is less specific than b.
|
|
||||||
* If a's stem length is shorter than b's stem length,
|
|
||||||
* -> a is less specific than b.
|
|
||||||
* If a's string length is shorter than b's string length,
|
|
||||||
* -> a is less specific than b.
|
|
||||||
* If a does not have a specified type and b does not,
|
|
||||||
* -> a is less specific than b.
|
|
||||||
*/
|
|
||||||
int fc_compare(file_context_node_t *a, file_context_node_t *b)
|
|
||||||
{
|
|
||||||
/* Check to see if either a or b have meta characters
|
|
||||||
* and the other doesn't. */
|
|
||||||
if (a->meta && !b->meta)
|
|
||||||
return -1;
|
|
||||||
if (b->meta && !a->meta)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Check to see if either a or b have a shorter stem
|
|
||||||
* length than the other. */
|
|
||||||
if (a->stem_len < b->stem_len)
|
|
||||||
return -1;
|
|
||||||
if (b->stem_len < a->stem_len)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Check to see if either a or b have a shorter string
|
|
||||||
* length than the other. */
|
|
||||||
if (a->str_len < b->str_len)
|
|
||||||
return -1;
|
|
||||||
if (b->str_len < a->str_len)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Check to see if either a or b has a specified type
|
|
||||||
* and the other doesn't. */
|
|
||||||
if (!a->file_type && b->file_type)
|
|
||||||
return -1;
|
|
||||||
if (!b->file_type && a->file_type)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* If none of the above conditions were satisfied,
|
|
||||||
* then a and b are equally specific. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* fc_merge
|
|
||||||
* Merges two sorted file context linked lists into one
|
|
||||||
* sorted one.
|
|
||||||
* Pass two lists a and b, and after the completion of fc_merge,
|
|
||||||
* the final list is contained in a, and b is empty.
|
|
||||||
*/
|
|
||||||
file_context_node_t *fc_merge(file_context_node_t *a,
|
|
||||||
file_context_node_t *b)
|
|
||||||
{
|
|
||||||
file_context_node_t *a_current;
|
|
||||||
file_context_node_t *b_current;
|
|
||||||
file_context_node_t *temp;
|
|
||||||
file_context_node_t *jumpto;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* If a is a empty list, and b is not,
|
|
||||||
* set a as b and proceed to the end. */
|
|
||||||
if (!a && b)
|
|
||||||
a = b;
|
|
||||||
/* If b is an empty list, leave a as it is. */
|
|
||||||
else if (!b) {
|
|
||||||
} else {
|
|
||||||
/* Make it so the list a has the lesser
|
|
||||||
* first element always. */
|
|
||||||
if (fc_compare(a, b) == 1) {
|
|
||||||
temp = a;
|
|
||||||
a = b;
|
|
||||||
b = temp;
|
|
||||||
}
|
|
||||||
a_current = a;
|
|
||||||
b_current = b;
|
|
||||||
|
|
||||||
/* Merge by inserting b's nodes in between a's nodes. */
|
|
||||||
while (a_current->next && b_current) {
|
|
||||||
jumpto = a_current->next;
|
|
||||||
|
|
||||||
/* Insert b's nodes in between the current a node
|
|
||||||
* and the next a node.*/
|
|
||||||
while (b_current && a_current->next &&
|
|
||||||
fc_compare(a_current->next,
|
|
||||||
b_current) != -1) {
|
|
||||||
|
|
||||||
|
|
||||||
temp = a_current->next;
|
|
||||||
a_current->next = b_current;
|
|
||||||
b_current = b_current->next;
|
|
||||||
a_current->next->next = temp;
|
|
||||||
a_current = a_current->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip all the inserted node from b to the
|
|
||||||
* next node in the original a. */
|
|
||||||
a_current = jumpto;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* if there is anything left in b to be inserted,
|
|
||||||
put it on the end */
|
|
||||||
if (b_current) {
|
|
||||||
a_current->next = b_current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* fc_merge_sort
|
|
||||||
* Sorts file contexts from least specific to more specific.
|
|
||||||
* The bucket linked list is passed and after the completion
|
|
||||||
* of the fc_merge_sort function, there is only one bucket
|
|
||||||
* (pointed to by master) that contains a linked list
|
|
||||||
* of all the file contexts, in sorted order.
|
|
||||||
* Explanation of the algorithm:
|
|
||||||
* The algorithm implemented in fc_merge_sort is an iterative
|
|
||||||
* implementation of merge sort.
|
|
||||||
* At first, each bucket has a linked list of file contexts
|
|
||||||
* that are 1 element each.
|
|
||||||
* Each pass, each odd numbered bucket is merged into the bucket
|
|
||||||
* before it. This halves the number of buckets each pass.
|
|
||||||
* It will continue passing over the buckets (as described above)
|
|
||||||
* until there is only one bucket left, containing the list of
|
|
||||||
* file contexts, sorted.
|
|
||||||
*/
|
|
||||||
void fc_merge_sort(file_context_bucket_t *master)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
file_context_bucket_t *current;
|
|
||||||
file_context_bucket_t *temp;
|
|
||||||
|
|
||||||
/* Loop until master is the only bucket left
|
|
||||||
* so that this will stop when master contains
|
|
||||||
* the sorted list. */
|
|
||||||
while (master->next) {
|
|
||||||
current = master;
|
|
||||||
|
|
||||||
/* This loop merges buckets two-by-two. */
|
|
||||||
while (current) {
|
|
||||||
|
|
||||||
if (current->next) {
|
|
||||||
|
|
||||||
current->data =
|
|
||||||
fc_merge(current->data,
|
|
||||||
current->next->data);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
temp = current->next;
|
|
||||||
current->next = current->next->next;
|
|
||||||
|
|
||||||
free(temp);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* fc_fill_data
|
|
||||||
* This processes a regular expression in a file context
|
|
||||||
* and sets the data held in file_context_node, namely
|
|
||||||
* meta, str_len and stem_len.
|
|
||||||
* The following changes are made to fc_node after the
|
|
||||||
* the completion of the function:
|
|
||||||
* fc_node->meta = 1 if path has a meta character, 0 if not.
|
|
||||||
* fc_node->str_len = The string length of the entire path
|
|
||||||
* fc_node->stem_len = The number of characters up until
|
|
||||||
* the first meta character.
|
|
||||||
*/
|
|
||||||
void fc_fill_data(file_context_node_t *fc_node)
|
|
||||||
{
|
|
||||||
int c = 0;
|
|
||||||
|
|
||||||
fc_node->meta = 0;
|
|
||||||
fc_node->stem_len = 0;
|
|
||||||
fc_node->str_len = 0;
|
|
||||||
|
|
||||||
/* Process until the string termination character
|
|
||||||
* has been reached.
|
|
||||||
* Note: this while loop has been adapted from
|
|
||||||
* spec_hasMetaChars in matchpathcon.c from
|
|
||||||
* libselinux-1.22. */
|
|
||||||
while (fc_node->path[c] != '\0') {
|
|
||||||
switch (fc_node->path[c]) {
|
|
||||||
case '.':
|
|
||||||
case '^':
|
|
||||||
case '$':
|
|
||||||
case '?':
|
|
||||||
case '*':
|
|
||||||
case '+':
|
|
||||||
case '|':
|
|
||||||
case '[':
|
|
||||||
case '(':
|
|
||||||
case '{':
|
|
||||||
/* If a meta character is found,
|
|
||||||
* set meta to one */
|
|
||||||
fc_node->meta = 1;
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
/* If a escape character is found,
|
|
||||||
* skip the next character. */
|
|
||||||
c++;
|
|
||||||
default:
|
|
||||||
/* If no meta character has been found yet,
|
|
||||||
* add one to the stem length. */
|
|
||||||
if (!fc_node->meta)
|
|
||||||
fc_node->stem_len++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fc_node->str_len++;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* main
|
|
||||||
* This program takes in two arguments, the input filename and the
|
|
||||||
* output filename. The input file should be syntactically correct.
|
|
||||||
* Overall what is done in the main is read in the file and store each
|
|
||||||
* line of code, sort it, then output it to the output file.
|
|
||||||
*/
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int lines;
|
|
||||||
size_t start, finish, regex_len, context_len;
|
|
||||||
size_t line_len, buf_len, i, j;
|
|
||||||
char *input_name, *output_name, *line_buf;
|
|
||||||
|
|
||||||
file_context_node_t *temp;
|
|
||||||
file_context_node_t *head;
|
|
||||||
file_context_node_t *current;
|
|
||||||
file_context_bucket_t *master;
|
|
||||||
file_context_bucket_t *bcurrent;
|
|
||||||
|
|
||||||
FILE *in_file, *out_file;
|
|
||||||
|
|
||||||
|
|
||||||
/* Check for the correct number of command line arguments. */
|
|
||||||
if (argc != 3) {
|
|
||||||
fprintf(stderr, "Usage: %s <infile> <outfile>\n",argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
input_name = argv[1];
|
|
||||||
output_name = argv[2];
|
|
||||||
|
|
||||||
i = j = lines = 0;
|
|
||||||
|
|
||||||
/* Open the input file. */
|
|
||||||
if (!(in_file = fopen(input_name, "r"))) {
|
|
||||||
fprintf(stderr, "Error: failure opening input file for read.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the head of the linked list. */
|
|
||||||
head = current = (file_context_node_t*)malloc(sizeof(file_context_node_t));
|
|
||||||
|
|
||||||
/* Parse the file into a file_context linked list. */
|
|
||||||
line_buf = NULL;
|
|
||||||
|
|
||||||
while ( getline(&line_buf, &buf_len, in_file) != -1 ){
|
|
||||||
line_len = strlen(line_buf);
|
|
||||||
if( line_len == 0 || line_len == 1)
|
|
||||||
continue;
|
|
||||||
/* Get rid of whitespace from the front of the line. */
|
|
||||||
for (i = 0; i < line_len; i++) {
|
|
||||||
if (!isspace(line_buf[i]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (i >= line_len)
|
|
||||||
continue;
|
|
||||||
/* Check if the line isn't empty and isn't a comment */
|
|
||||||
if (line_buf[i] == '#')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* We have a valid line - allocate a new node. */
|
|
||||||
temp = (file_context_node_t *)malloc(sizeof(file_context_node_t));
|
|
||||||
if (!temp) {
|
|
||||||
fprintf(stderr, "Error: failure allocating memory.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
temp->next = NULL;
|
|
||||||
memset(temp, 0, sizeof(file_context_node_t));
|
|
||||||
|
|
||||||
/* Parse out the regular expression from the line. */
|
|
||||||
start = i;
|
|
||||||
|
|
||||||
|
|
||||||
while (i < line_len && (!isspace(line_buf[i])))
|
|
||||||
i++;
|
|
||||||
finish = i;
|
|
||||||
|
|
||||||
|
|
||||||
regex_len = finish - start;
|
|
||||||
|
|
||||||
if (regex_len == 0) {
|
|
||||||
file_context_node_destroy(temp);
|
|
||||||
free(temp);
|
|
||||||
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
temp->path = (char*)strndup(&line_buf[start], regex_len);
|
|
||||||
if (!temp->path) {
|
|
||||||
file_context_node_destroy(temp);
|
|
||||||
free(temp);
|
|
||||||
fprintf(stderr, "Error: failure allocating memory.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get rid of whitespace after the regular expression. */
|
|
||||||
for (; i < line_len; i++) {
|
|
||||||
|
|
||||||
if (!isspace(line_buf[i]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == line_len) {
|
|
||||||
file_context_node_destroy(temp);
|
|
||||||
free(temp);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse out the type from the line (if it
|
|
||||||
* is there). */
|
|
||||||
if (line_buf[i] == '-') {
|
|
||||||
temp->file_type = (char *)malloc(sizeof(char) * 3);
|
|
||||||
if (!(temp->file_type)) {
|
|
||||||
fprintf(stderr, "Error: failure allocating memory.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( i + 2 >= line_len ) {
|
|
||||||
file_context_node_destroy(temp);
|
|
||||||
free(temp);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill the type into the array. */
|
|
||||||
temp->file_type[0] = line_buf[i];
|
|
||||||
temp->file_type[1] = line_buf[i + 1];
|
|
||||||
i += 2;
|
|
||||||
temp->file_type[2] = 0;
|
|
||||||
|
|
||||||
/* Get rid of whitespace after the type. */
|
|
||||||
for (; i < line_len; i++) {
|
|
||||||
if (!isspace(line_buf[i]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == line_len) {
|
|
||||||
|
|
||||||
file_context_node_destroy(temp);
|
|
||||||
free(temp);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse out the context from the line. */
|
|
||||||
start = i;
|
|
||||||
while (i < line_len && (!isspace(line_buf[i])))
|
|
||||||
i++;
|
|
||||||
finish = i;
|
|
||||||
|
|
||||||
context_len = finish - start;
|
|
||||||
|
|
||||||
temp->context = (char*)strndup(&line_buf[start], context_len);
|
|
||||||
if (!temp->context) {
|
|
||||||
file_context_node_destroy(temp);
|
|
||||||
free(temp);
|
|
||||||
fprintf(stderr, "Error: failure allocating memory.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set all the data about the regular
|
|
||||||
* expression. */
|
|
||||||
fc_fill_data(temp);
|
|
||||||
|
|
||||||
/* Link this line of code at the end of
|
|
||||||
* the linked list. */
|
|
||||||
current->next = temp;
|
|
||||||
current = current->next;
|
|
||||||
lines++;
|
|
||||||
|
|
||||||
|
|
||||||
free(line_buf);
|
|
||||||
line_buf = NULL;
|
|
||||||
}
|
|
||||||
fclose(in_file);
|
|
||||||
|
|
||||||
/* Create the bucket linked list from the earlier linked list. */
|
|
||||||
current = head->next;
|
|
||||||
bcurrent = master =
|
|
||||||
(file_context_bucket_t *)
|
|
||||||
malloc(sizeof(file_context_bucket_t));
|
|
||||||
|
|
||||||
/* Go until all the nodes have been put in individual buckets. */
|
|
||||||
while (current) {
|
|
||||||
/* Copy over the file context line into the bucket. */
|
|
||||||
bcurrent->data = current;
|
|
||||||
current = current->next;
|
|
||||||
|
|
||||||
/* Detatch the node in the bucket from the old list. */
|
|
||||||
bcurrent->data->next = NULL;
|
|
||||||
|
|
||||||
/* If there should be another bucket, put one at the end. */
|
|
||||||
if (current) {
|
|
||||||
bcurrent->next =
|
|
||||||
(file_context_bucket_t *)
|
|
||||||
malloc(sizeof(file_context_bucket_t));
|
|
||||||
if (!(bcurrent->next)) {
|
|
||||||
printf
|
|
||||||
("Error: failure allocating memory.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure the new bucket thinks it's the end of the
|
|
||||||
* list. */
|
|
||||||
bcurrent->next->next = NULL;
|
|
||||||
|
|
||||||
bcurrent = bcurrent->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort the bucket list. */
|
|
||||||
fc_merge_sort(master);
|
|
||||||
|
|
||||||
/* Open the output file. */
|
|
||||||
if (!(out_file = fopen(argv[2], "w"))) {
|
|
||||||
printf("Error: failure opening output file for write.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output the sorted file_context linked list to the output file. */
|
|
||||||
current = master->data;
|
|
||||||
while (current) {
|
|
||||||
/* Output the path. */
|
|
||||||
fprintf(out_file, "%s\t\t", current->path);
|
|
||||||
|
|
||||||
/* Output the type, if there is one. */
|
|
||||||
if (current->file_type) {
|
|
||||||
fprintf(out_file, "%s\t", current->file_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output the context. */
|
|
||||||
fprintf(out_file, "%s\n", current->context);
|
|
||||||
|
|
||||||
/* Remove the node. */
|
|
||||||
temp = current;
|
|
||||||
current = current->next;
|
|
||||||
|
|
||||||
file_context_node_destroy(temp);
|
|
||||||
free(temp);
|
|
||||||
|
|
||||||
}
|
|
||||||
free(master);
|
|
||||||
|
|
||||||
fclose(out_file);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,308 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
# Author: Donald Miner <dminer@tresys.com>
|
|
||||||
#
|
|
||||||
# Copyright (C) 2005 Tresys Technology, LLC
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, version 2.
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
This script generates an object class perm definition file.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
USERSPACE_CLASS = "userspace"
|
|
||||||
|
|
||||||
class Class:
|
|
||||||
"""
|
|
||||||
This object stores an access vector class.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, name, perms, common):
|
|
||||||
# The name of the class.
|
|
||||||
self.name = name
|
|
||||||
|
|
||||||
# A list of permissions the class contains.
|
|
||||||
self.perms = perms
|
|
||||||
|
|
||||||
# True if the class is declared as common, False if not.
|
|
||||||
self.common = common
|
|
||||||
|
|
||||||
def get_perms(name, av_db, common):
|
|
||||||
"""
|
|
||||||
Returns the list of permissions contained within an access vector
|
|
||||||
class that is stored in the access vector database av_db.
|
|
||||||
Returns an empty list if the object name is not found.
|
|
||||||
Specifiy whether get_perms is to return the class or the
|
|
||||||
common set of permissions with the boolean value 'common',
|
|
||||||
which is important in the case of having duplicate names (such as
|
|
||||||
class file and common file).
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Traverse through the access vector database and try to find the
|
|
||||||
# object with the name passed.
|
|
||||||
for obj in av_db:
|
|
||||||
if obj.name == name and obj.common == common:
|
|
||||||
return obj.perms
|
|
||||||
|
|
||||||
return []
|
|
||||||
|
|
||||||
def get_av_db(file_name):
|
|
||||||
"""
|
|
||||||
Returns an access vector database generated from the file file_name.
|
|
||||||
"""
|
|
||||||
# This function takes a file, reads the data, parses it and returns
|
|
||||||
# a list of access vector classes.
|
|
||||||
# Reading into av_data:
|
|
||||||
# The file specified will be read line by line. Each line will have
|
|
||||||
# its comments removed. Once comments are removed, each 'word' (text
|
|
||||||
# seperated by whitespace) and braces will be split up into seperate
|
|
||||||
# strings and appended to the av_data list, in the order they were
|
|
||||||
# read.
|
|
||||||
# Parsing av_data:
|
|
||||||
# Parsing is done using a queue implementation of the av_data list.
|
|
||||||
# Each time a word is used, it is dequeued afterwards. Each loop in
|
|
||||||
# the while loop below will read in key words and dequeue expected
|
|
||||||
# words and values. At the end of each loop, a Class containing the
|
|
||||||
# name, permissions and whether it is a common or not will be appended
|
|
||||||
# to the database. Lots of errors are caught here, almost all checking
|
|
||||||
# if a token is expected but EOF is reached.
|
|
||||||
# Now the list of Class objects is returned.
|
|
||||||
|
|
||||||
av_file = open(file_name, "r")
|
|
||||||
av_data = []
|
|
||||||
# Read the file and strip out comments on the way.
|
|
||||||
# At the end of the loop, av_data will contain a list of individual
|
|
||||||
# words. i.e. ['common', 'file', '{', ...]. All comments and whitespace
|
|
||||||
# will be gone.
|
|
||||||
while True:
|
|
||||||
av_line = av_file.readline()
|
|
||||||
|
|
||||||
# If EOF has been reached:
|
|
||||||
if not av_line:
|
|
||||||
break
|
|
||||||
|
|
||||||
# Check if there is a comment, and if there is, remove it.
|
|
||||||
comment_index = av_line.find("#")
|
|
||||||
if comment_index != -1:
|
|
||||||
av_line = av_line[:comment_index]
|
|
||||||
|
|
||||||
# Pad the braces with whitespace so that they are split into
|
|
||||||
# their own word. It doesn't matter if there will be extra
|
|
||||||
# white space, it'll get thrown away when the string is split.
|
|
||||||
av_line.replace("{"," { ")
|
|
||||||
av_line.replace("}"," } ")
|
|
||||||
|
|
||||||
# Split up the words on the line and add it to av_data.
|
|
||||||
av_data += av_line.split()
|
|
||||||
|
|
||||||
av_file.close()
|
|
||||||
|
|
||||||
# Parsing the file:
|
|
||||||
# The implementation of this parse is a queue. We use the list of words
|
|
||||||
# from av_data and use the front element, then dequeue it. Each
|
|
||||||
# loop of this while is a common or class declaration. Several
|
|
||||||
# expected tokens are parsed and dequeued out of av_data for each loop.
|
|
||||||
# At the end of the loop, database will contain a list of Class objects.
|
|
||||||
# i.e. [Class('name',['perm1','perm2',...],'True'), ...]
|
|
||||||
# Dequeue from the beginning of the list until av_data is empty:
|
|
||||||
database = []
|
|
||||||
while len(av_data) != 0:
|
|
||||||
# At the beginning of every loop, the next word should be
|
|
||||||
# "common" or "class", meaning that each loop is a common
|
|
||||||
# or class declaration.
|
|
||||||
# av_data = av_data[1:] removes the first element in the
|
|
||||||
# list, this is what is dequeueing data.
|
|
||||||
|
|
||||||
# Figure out whether the next class will be a common or a class.
|
|
||||||
if av_data[0] == "class":
|
|
||||||
common = False
|
|
||||||
elif av_data[0] == "common":
|
|
||||||
common = True
|
|
||||||
else:
|
|
||||||
error("Unexpected token in file " + file_name + ": "\
|
|
||||||
+ av_data[0] + ".")
|
|
||||||
|
|
||||||
# Dequeue the "class" or "common" key word.
|
|
||||||
av_data = av_data[1:]
|
|
||||||
|
|
||||||
if len(av_data) == 0:
|
|
||||||
error("Missing token in file " + file_name + ".")
|
|
||||||
|
|
||||||
# Get and dequeue the name of the class or common.
|
|
||||||
name = av_data[0]
|
|
||||||
av_data = av_data[1:]
|
|
||||||
|
|
||||||
# Retrieve the permissions inherited from a common set:
|
|
||||||
perms = []
|
|
||||||
# If the object we are working with is a class, since only
|
|
||||||
# classes inherit:
|
|
||||||
if common == False:
|
|
||||||
if len(av_data) == 0:
|
|
||||||
error("Missing token in file " + file_name + ".")
|
|
||||||
|
|
||||||
# If the class inherits from something else:
|
|
||||||
if av_data[0] == "inherits":
|
|
||||||
# Dequeue the "inherits" key word.
|
|
||||||
av_data = av_data[1:]
|
|
||||||
|
|
||||||
if len(av_data) == 0:
|
|
||||||
error("Missing token in file "\
|
|
||||||
+ file_name + " for " +\
|
|
||||||
keyword + " " + name + ".")
|
|
||||||
|
|
||||||
# av_data[0] is the name of the parent.
|
|
||||||
# Append the permissions of the parent to
|
|
||||||
# the current class' permissions.
|
|
||||||
perms += get_perms(av_data[0], database, True)
|
|
||||||
|
|
||||||
# Dequeue the name of the parent.
|
|
||||||
av_data = av_data[1:]
|
|
||||||
|
|
||||||
# Retrieve the permissions defined with this set.
|
|
||||||
if len(av_data) > 0 and av_data[0] == "{":
|
|
||||||
# Dequeue the "{"
|
|
||||||
av_data = av_data[1:]
|
|
||||||
|
|
||||||
# Keep appending permissions until a close brace is
|
|
||||||
# found.
|
|
||||||
while av_data[0] != "}":
|
|
||||||
if av_data[0] == "{":
|
|
||||||
error("Extra '{' in file " +\
|
|
||||||
file_name + ".")
|
|
||||||
|
|
||||||
# Add the permission name.
|
|
||||||
perms.append(av_data[0])
|
|
||||||
|
|
||||||
# Dequeue the permission name.
|
|
||||||
av_data = av_data[1:]
|
|
||||||
|
|
||||||
if len(av_data) == 0:
|
|
||||||
error("Missing token '}' in file "\
|
|
||||||
+ file_name + ".")
|
|
||||||
|
|
||||||
# Dequeue the "}"
|
|
||||||
av_data = av_data[1:]
|
|
||||||
|
|
||||||
# Add the new access vector class to the database.
|
|
||||||
database.append(Class(name, perms, common))
|
|
||||||
|
|
||||||
return database
|
|
||||||
|
|
||||||
def get_sc_db(file_name):
|
|
||||||
"""
|
|
||||||
Returns a security class database generated from the file file_name.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Read the file then close it.
|
|
||||||
sc_file = open(file_name)
|
|
||||||
sc_data = sc_file.readlines()
|
|
||||||
sc_file.close()
|
|
||||||
|
|
||||||
# For each line in the security classes file, add the name of the class
|
|
||||||
# and whether it is a userspace class or not to the security class
|
|
||||||
# database.
|
|
||||||
database = []
|
|
||||||
for line in sc_data:
|
|
||||||
line = line.lstrip()
|
|
||||||
# If the line is empty or the entire line is a comment, skip.
|
|
||||||
if line == "" or line[0] == "#":
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Check if the comment to the right of the permission matches
|
|
||||||
# USERSPACE_CLASS.
|
|
||||||
comment_index = line.find("#")
|
|
||||||
if comment_index != -1 and line[comment_index+1:].strip() == USERSPACE_CLASS:
|
|
||||||
userspace = True
|
|
||||||
else:
|
|
||||||
userspace = False
|
|
||||||
|
|
||||||
# All lines should be in the format "class NAME", meaning
|
|
||||||
# it should have two tokens and the first token should be
|
|
||||||
# "class".
|
|
||||||
split_line = line.split()
|
|
||||||
if len(split_line) < 2 or split_line[0] != "class":
|
|
||||||
error("Wrong syntax: " + line)
|
|
||||||
|
|
||||||
# Add the class's name (split_line[1]) and whether it is a
|
|
||||||
# userspace class or not to the database.
|
|
||||||
# This is appending a tuple of (NAME,USERSPACE), where NAME is
|
|
||||||
# the name of the security class and USERSPACE is True if
|
|
||||||
# if it has "# USERSPACE_CLASS" on the end of the line, False
|
|
||||||
# if not.
|
|
||||||
database.append((split_line[1], userspace))
|
|
||||||
|
|
||||||
return database
|
|
||||||
|
|
||||||
def gen_class_perms(av_db, sc_db):
|
|
||||||
"""
|
|
||||||
Generates a class permissions document and returns it.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Define class template:
|
|
||||||
class_perms_line = "define(`all_%s_perms',`{ %s}')\n"
|
|
||||||
|
|
||||||
# Generate the defines for the individual class permissions.
|
|
||||||
class_perms = ""
|
|
||||||
for obj in av_db:
|
|
||||||
# Don't output commons
|
|
||||||
if obj.common == True:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Get the list of permissions from the specified class.
|
|
||||||
perms = get_perms(obj.name, av_db, False)
|
|
||||||
|
|
||||||
# Merge all the permissions into one string with one space
|
|
||||||
# padding.
|
|
||||||
perm_str = ""
|
|
||||||
for perm in perms:
|
|
||||||
perm_str += perm + " "
|
|
||||||
|
|
||||||
# Add the line to the class_perms
|
|
||||||
class_perms += class_perms_line % (obj.name, perm_str)
|
|
||||||
class_perms += "\n"
|
|
||||||
|
|
||||||
# Generate the kernel_class_perms and userspace_class_perms sets.
|
|
||||||
class_line = "\tclass %s all_%s_perms;\n"
|
|
||||||
kernel_class_perms = "define(`all_kernel_class_perms',`\n"
|
|
||||||
userspace_class_perms = "define(`all_userspace_class_perms',`\n"
|
|
||||||
# For each (NAME,USERSPACE) tuple, add the class to the appropriate
|
|
||||||
# class permission set.
|
|
||||||
for name, userspace in sc_db:
|
|
||||||
if userspace:
|
|
||||||
userspace_class_perms += class_line % (name, name)
|
|
||||||
else:
|
|
||||||
kernel_class_perms += class_line % (name, name)
|
|
||||||
kernel_class_perms += "')\n\n"
|
|
||||||
userspace_class_perms += "')\n"
|
|
||||||
|
|
||||||
# Throw all the strings together and return the string.
|
|
||||||
return class_perms + kernel_class_perms + userspace_class_perms
|
|
||||||
|
|
||||||
def error(error):
|
|
||||||
"""
|
|
||||||
Print an error message and exit.
|
|
||||||
"""
|
|
||||||
|
|
||||||
sys.stderr.write("%s exiting for: " % sys.argv[0])
|
|
||||||
sys.stderr.write("%s\n" % error)
|
|
||||||
sys.stderr.flush()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# MAIN PROGRAM
|
|
||||||
app_name = sys.argv[0]
|
|
||||||
|
|
||||||
if len(sys.argv) != 3:
|
|
||||||
error("Incorrect input.\nUsage: " + sys.argv[0] + " access_vectors security_classes" )
|
|
||||||
|
|
||||||
# argv[1] is the access vector file.
|
|
||||||
av_file = sys.argv[1]
|
|
||||||
|
|
||||||
# argv[2] is the security class file.
|
|
||||||
sc_file = sys.argv[2]
|
|
||||||
|
|
||||||
# Output the class permissions document.
|
|
||||||
sys.stdout.write(gen_class_perms(get_av_db(av_file), get_sc_db(sc_file)))
|
|
@ -1,481 +0,0 @@
|
|||||||
#! /usr/bin/env python
|
|
||||||
# Copyright (C) 2004 Tresys Technology, LLC
|
|
||||||
# see file 'COPYING' for use and warranty information
|
|
||||||
#
|
|
||||||
# genhomedircon - this script is used to generate file context
|
|
||||||
# configuration entries for user home directories based on their
|
|
||||||
# default roles and is run when building the policy. Specifically, we
|
|
||||||
# replace HOME_ROOT, HOME_DIR, and ROLE macros in .fc files with
|
|
||||||
# generic and user-specific values.
|
|
||||||
#
|
|
||||||
# Based off original script by Dan Walsh, <dwalsh@redhat.com>
|
|
||||||
#
|
|
||||||
# ASSUMPTIONS:
|
|
||||||
#
|
|
||||||
# The file CONTEXTDIR/files/homedir_template exists. This file is used to
|
|
||||||
# set up the home directory context for each real user.
|
|
||||||
#
|
|
||||||
# If a user has more than one role in CONTEXTDIR/local.users, genhomedircon uses
|
|
||||||
# the first role in the list.
|
|
||||||
#
|
|
||||||
# If a user is not listed in CONTEXTDIR/local.users, he will default to user_u, role user
|
|
||||||
#
|
|
||||||
# "Real" users (as opposed to system users) are those whose UID is greater than
|
|
||||||
# or equal STARTING_UID (usually 500) and whose login is not a member of
|
|
||||||
# EXCLUDE_LOGINS. Users who are explicitly defined in CONTEXTDIR/local.users
|
|
||||||
# are always "real" (including root, in the default configuration).
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Old ASSUMPTIONS:
|
|
||||||
#
|
|
||||||
# If a user has more than one role in FILECONTEXTDIR/users, genhomedircon uses
|
|
||||||
# the first role in the list.
|
|
||||||
#
|
|
||||||
# If a user is not listed in FILECONTEXTDIR/users, genhomedircon assumes that
|
|
||||||
# the user's home dir will be found in one of the HOME_ROOTs.
|
|
||||||
#
|
|
||||||
# "Real" users (as opposed to system users) are those whose UID is greater than
|
|
||||||
# or equal STARTING_UID (usually 500) and whose login is not a member of
|
|
||||||
# EXCLUDE_LOGINS. Users who are explicitly defined in FILECONTEXTDIR/users
|
|
||||||
# are always "real" (including root, in the default configuration).
|
|
||||||
#
|
|
||||||
|
|
||||||
import commands, sys, os, pwd, string, getopt, re
|
|
||||||
|
|
||||||
EXCLUDE_LOGINS=["/sbin/nologin", "/bin/false"]
|
|
||||||
|
|
||||||
def getStartingUID():
|
|
||||||
starting_uid = sys.maxint
|
|
||||||
rc=commands.getstatusoutput("grep -h '^UID_MIN' /etc/login.defs")
|
|
||||||
if rc[0] == 0:
|
|
||||||
uid_min = re.sub("^UID_MIN[^0-9]*", "", rc[1])
|
|
||||||
#stip any comment from the end of the line
|
|
||||||
uid_min = uid_min.split("#")[0]
|
|
||||||
uid_min = uid_min.strip()
|
|
||||||
if int(uid_min) < starting_uid:
|
|
||||||
starting_uid = int(uid_min)
|
|
||||||
rc=commands.getstatusoutput("grep -h '^LU_UIDNUMBER' /etc/libuser.conf")
|
|
||||||
if rc[0] == 0:
|
|
||||||
lu_uidnumber = re.sub("^LU_UIDNUMBER[^0-9]*", "", rc[1])
|
|
||||||
#stip any comment from the end of the line
|
|
||||||
lu_uidnumber = re.sub("[ \t].*", "", lu_uidnumber)
|
|
||||||
lu_uidnumber = lu_uidnumber.split("#")[0]
|
|
||||||
lu_uidnumber = lu_uidnumber.strip()
|
|
||||||
if int(lu_uidnumber) < starting_uid:
|
|
||||||
starting_uid = int(lu_uidnumber)
|
|
||||||
if starting_uid == sys.maxint:
|
|
||||||
starting_uid = 500
|
|
||||||
return starting_uid
|
|
||||||
|
|
||||||
#############################################################################
|
|
||||||
#
|
|
||||||
# This section is just for backwards compatability
|
|
||||||
#
|
|
||||||
#############################################################################
|
|
||||||
def getPrefixes():
|
|
||||||
ulist = pwd.getpwall()
|
|
||||||
STARTING_UID=getStartingUID()
|
|
||||||
prefixes = {}
|
|
||||||
for u in ulist:
|
|
||||||
if u[2] >= STARTING_UID and \
|
|
||||||
not u[6] in EXCLUDE_LOGINS and \
|
|
||||||
u[5] != "/" and \
|
|
||||||
string.count(u[5], "/") > 1:
|
|
||||||
prefix = u[5][:string.rfind(u[5], "/")]
|
|
||||||
if not prefixes.has_key(prefix):
|
|
||||||
prefixes[prefix] = ""
|
|
||||||
return prefixes
|
|
||||||
|
|
||||||
def getUsers(filecontextdir):
|
|
||||||
rc = commands.getstatusoutput("grep ^user %s/users" % filecontextdir)
|
|
||||||
udict = {}
|
|
||||||
if rc[0] == 0:
|
|
||||||
ulist = rc[1].strip().split("\n")
|
|
||||||
for u in ulist:
|
|
||||||
user = u.split()
|
|
||||||
try:
|
|
||||||
if user[1] == "user_u" or user[1] == "system_u":
|
|
||||||
continue
|
|
||||||
# !!! chooses first role in the list to use in the file context !!!
|
|
||||||
role = user[3]
|
|
||||||
if role == "{":
|
|
||||||
role = user[4]
|
|
||||||
role = role.split("_r")[0]
|
|
||||||
home = pwd.getpwnam(user[1])[5]
|
|
||||||
if home == "/":
|
|
||||||
continue
|
|
||||||
prefs = {}
|
|
||||||
prefs["role"] = role
|
|
||||||
prefs["home"] = home
|
|
||||||
udict[user[1]] = prefs
|
|
||||||
except KeyError:
|
|
||||||
sys.stderr.write("The user \"%s\" is not present in the passwd file, skipping...\n" % user[1])
|
|
||||||
return udict
|
|
||||||
|
|
||||||
def update(filecontext, user, prefs):
|
|
||||||
rc=commands.getstatusoutput("grep -h '^HOME_DIR' %s | grep -v vmware | sed -e 's|HOME_DIR|%s|' -e 's/ROLE/%s/' -e 's/system_u/%s/'" % (filecontext, prefs["home"], prefs["role"], user))
|
|
||||||
if rc[0] == 0:
|
|
||||||
print rc[1]
|
|
||||||
else:
|
|
||||||
errorExit(string.join("grep/sed error ", rc[1]))
|
|
||||||
return rc
|
|
||||||
|
|
||||||
def oldgenhomedircon(filecontextdir, filecontext):
|
|
||||||
sys.stderr.flush()
|
|
||||||
|
|
||||||
if os.path.isdir(filecontextdir) == 0:
|
|
||||||
sys.stderr.write("New usage is the following\n")
|
|
||||||
usage()
|
|
||||||
#We are going to define home directory used by libuser and show-utils as a home directory root
|
|
||||||
prefixes = {}
|
|
||||||
rc=commands.getstatusoutput("grep -h '^HOME' /etc/default/useradd")
|
|
||||||
if rc[0] == 0:
|
|
||||||
homedir = rc[1].split("=")[1]
|
|
||||||
homedir = homedir.split("#")[0]
|
|
||||||
homedir = homedir.strip()
|
|
||||||
if not prefixes.has_key(homedir):
|
|
||||||
prefixes[homedir] = ""
|
|
||||||
else:
|
|
||||||
#rc[0] == 256 means the file was there, we read it, but the grep didn't match
|
|
||||||
if rc[0] != 256:
|
|
||||||
sys.stderr.write("%s\n" % rc[1])
|
|
||||||
sys.stderr.write("You do not have access to /etc/default/useradd HOME=\n")
|
|
||||||
sys.stderr.flush()
|
|
||||||
|
|
||||||
|
|
||||||
rc=commands.getstatusoutput("grep -h '^LU_HOMEDIRECTORY' /etc/libuser.conf")
|
|
||||||
if rc[0] == 0:
|
|
||||||
homedir = rc[1].split("=")[1]
|
|
||||||
homedir = homedir.split("#")[0]
|
|
||||||
homedir = homedir.strip()
|
|
||||||
homedir = re.sub(r"[^/a-zA-Z0-9].*$", "", homedir)
|
|
||||||
if not prefixes.has_key(homedir):
|
|
||||||
prefixes[homedir] = ""
|
|
||||||
|
|
||||||
#the idea is that we need to find all of the home_root_t directories we do this by just accepting
|
|
||||||
#any default home directory defined by either /etc/libuser.conf or /etc/default/useradd
|
|
||||||
#we then get the potential home directory roots from /etc/passwd or nis or wherever and look at
|
|
||||||
#the defined homedir for all users with UID > STARTING_UID. This list of possible root homedirs
|
|
||||||
#is then checked to see if it has an explicite context defined in the file_contexts. Explicit
|
|
||||||
#is any regex that would match it which does not end with .*$ or .+$ since those are general
|
|
||||||
#recursive matches. We then take any regex which ends with [pattern](/.*)?$ and just check against
|
|
||||||
#[pattern]
|
|
||||||
potential_prefixes = getPrefixes()
|
|
||||||
prefix_regex = {}
|
|
||||||
#this works by grepping the file_contexts for
|
|
||||||
# 1. ^/ makes sure this is not a comment
|
|
||||||
# 2. prints only the regex in the first column first cut on \t then on space
|
|
||||||
rc=commands.getstatusoutput("grep \"^/\" %s | cut -f 1 | cut -f 1 -d \" \" " % (sys.argv[2]) )
|
|
||||||
if rc[0] == 0:
|
|
||||||
prefix_regex = rc[1].split("\n")
|
|
||||||
else:
|
|
||||||
sys.stderr.write("%s\n" % rc[1])
|
|
||||||
sys.stderr.write("You do not have access to grep/cut/the file contexts\n")
|
|
||||||
sys.stderr.flush()
|
|
||||||
for potential in potential_prefixes.keys():
|
|
||||||
addme = 1
|
|
||||||
for regex in prefix_regex:
|
|
||||||
#match a trailing (/*)? which is actually a bug in rpc_pipefs
|
|
||||||
regex = re.sub("\(/\*\)\?$", "", regex)
|
|
||||||
#match a trailing .+
|
|
||||||
regex = re.sub("\.+$", "", regex)
|
|
||||||
#match a trailing .*
|
|
||||||
regex = re.sub("\.\*$", "", regex)
|
|
||||||
#strip a (/.*)? which matches anything trailing to a /*$ which matches trailing /'s
|
|
||||||
regex = re.sub("\(\/\.\*\)\?", "", regex)
|
|
||||||
regex = regex + "/*$"
|
|
||||||
if re.search(regex, potential, 0):
|
|
||||||
addme = 0
|
|
||||||
if addme == 1:
|
|
||||||
if not prefixes.has_key(potential):
|
|
||||||
prefixes[potential] = ""
|
|
||||||
|
|
||||||
|
|
||||||
if prefixes.__eq__({}):
|
|
||||||
sys.stderr.write("LU_HOMEDIRECTORY not set in /etc/libuser.conf\n")
|
|
||||||
sys.stderr.write("HOME= not set in /etc/default/useradd\n")
|
|
||||||
sys.stderr.write("And no users with a reasonable homedir found in passwd/nis/ldap/etc...\n")
|
|
||||||
sys.stderr.write("Assuming /home is the root of home directories\n")
|
|
||||||
sys.stderr.flush()
|
|
||||||
prefixes["/home"] = ""
|
|
||||||
|
|
||||||
# There may be a more elegant sed script to expand a macro to multiple lines, but this works
|
|
||||||
sed_root = "h; s|^HOME_ROOT|%s|" % (string.join(prefixes.keys(), "|; p; g; s|^HOME_ROOT|"),)
|
|
||||||
sed_dir = "h; s|^HOME_DIR|%s/[^/]+|; s|ROLE_|user_|" % (string.join(prefixes.keys(), "/[^/]+|; s|ROLE_|user_|; p; g; s|^HOME_DIR|"),)
|
|
||||||
|
|
||||||
# Fill in HOME_ROOT, HOME_DIR, and ROLE for users not explicitly defined in /etc/security/selinux/src/policy/users
|
|
||||||
rc=commands.getstatusoutput("sed -e \"/^HOME_ROOT/{%s}\" -e \"/^HOME_DIR/{%s}\" %s" % (sed_root, sed_dir, filecontext))
|
|
||||||
if rc[0] == 0:
|
|
||||||
print rc[1]
|
|
||||||
else:
|
|
||||||
errorExit(string.join("sed error ", rc[1]))
|
|
||||||
|
|
||||||
users = getUsers(filecontextdir)
|
|
||||||
print "\n#\n# User-specific file contexts\n#\n"
|
|
||||||
|
|
||||||
# Fill in HOME and ROLE for users that are defined
|
|
||||||
for u in users.keys():
|
|
||||||
update(filecontext, u, users[u])
|
|
||||||
|
|
||||||
#############################################################################
|
|
||||||
#
|
|
||||||
# End of backwards compatability section
|
|
||||||
#
|
|
||||||
#############################################################################
|
|
||||||
|
|
||||||
def getDefaultHomeDir():
|
|
||||||
ret = []
|
|
||||||
rc=commands.getstatusoutput("grep -h '^HOME' /etc/default/useradd")
|
|
||||||
if rc[0] == 0:
|
|
||||||
homedir = rc[1].split("=")[1]
|
|
||||||
homedir = homedir.split("#")[0]
|
|
||||||
homedir = homedir.strip()
|
|
||||||
if not homedir in ret:
|
|
||||||
ret.append(homedir)
|
|
||||||
else:
|
|
||||||
#rc[0] == 256 means the file was there, we read it, but the grep didn't match
|
|
||||||
if rc[0] != 256:
|
|
||||||
sys.stderr.write("%s\n" % rc[1])
|
|
||||||
sys.stderr.write("You do not have access to /etc/default/useradd HOME=\n")
|
|
||||||
sys.stderr.flush()
|
|
||||||
rc=commands.getstatusoutput("grep -h '^LU_HOMEDIRECTORY' /etc/libuser.conf")
|
|
||||||
if rc[0] == 0:
|
|
||||||
homedir = rc[1].split("=")[1]
|
|
||||||
homedir = homedir.split("#")[0]
|
|
||||||
homedir = homedir.strip()
|
|
||||||
if not homedir in ret:
|
|
||||||
ret.append(homedir)
|
|
||||||
else:
|
|
||||||
#rc[0] == 256 means the file was there, we read it, but the grep didn't match
|
|
||||||
if rc[0] != 256:
|
|
||||||
sys.stderr.write("%s\n" % rc[1])
|
|
||||||
sys.stderr.write("You do not have access to /etc/libuser.conf LU_HOMEDIRECTORY=\n")
|
|
||||||
sys.stderr.flush()
|
|
||||||
if ret == []:
|
|
||||||
ret.append("/home")
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def getSELinuxType(directory):
|
|
||||||
rc=commands.getstatusoutput("grep ^SELINUXTYPE= %s/config" % directory)
|
|
||||||
if rc[0]==0:
|
|
||||||
return rc[1].split("=")[-1].strip()
|
|
||||||
return "targeted"
|
|
||||||
|
|
||||||
def usage(error = ""):
|
|
||||||
if error != "":
|
|
||||||
sys.stderr.write("%s\n" % error)
|
|
||||||
sys.stderr.write("Usage: %s [ -d selinuxdir ] [-n | --nopasswd] [-t selinuxtype ]\n" % sys.argv[0])
|
|
||||||
sys.stderr.flush()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def warning(warning = ""):
|
|
||||||
sys.stderr.write("%s\n" % warning)
|
|
||||||
sys.stderr.flush()
|
|
||||||
|
|
||||||
def errorExit(error):
|
|
||||||
sys.stderr.write("%s exiting for: " % sys.argv[0])
|
|
||||||
sys.stderr.write("%s\n" % error)
|
|
||||||
sys.stderr.flush()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
class selinuxConfig:
|
|
||||||
def __init__(self, selinuxdir="/etc/selinux", type="targeted", usepwd=1):
|
|
||||||
self.type=type
|
|
||||||
self.selinuxdir=selinuxdir +"/"
|
|
||||||
self.contextdir="/contexts"
|
|
||||||
self.filecontextdir=self.contextdir+"/files"
|
|
||||||
self.usepwd=usepwd
|
|
||||||
|
|
||||||
def getFileContextDir(self):
|
|
||||||
return self.selinuxdir+self.type+self.filecontextdir
|
|
||||||
|
|
||||||
def getFileContextFile(self):
|
|
||||||
return self.getFileContextDir()+"/file_contexts"
|
|
||||||
|
|
||||||
def getContextDir(self):
|
|
||||||
return self.selinuxdir+self.type+self.contextdir
|
|
||||||
|
|
||||||
def getHomeDirTemplate(self):
|
|
||||||
return self.getFileContextDir()+"/homedir_template"
|
|
||||||
|
|
||||||
def getHomeRootContext(self, homedir):
|
|
||||||
rc=commands.getstatusoutput("grep HOME_ROOT %s | sed -e \"s|^HOME_ROOT|%s|\"" % ( self.getHomeDirTemplate(), homedir))
|
|
||||||
if rc[0] == 0:
|
|
||||||
return rc[1]+"\n"
|
|
||||||
else:
|
|
||||||
errorExit(string.join("sed error ", rc[1]))
|
|
||||||
|
|
||||||
def getUsersFile(self):
|
|
||||||
return self.selinuxdir+self.type+"/users/local.users"
|
|
||||||
|
|
||||||
def getSystemUsersFile(self):
|
|
||||||
return self.selinuxdir+self.type+"/users/system.users"
|
|
||||||
|
|
||||||
def heading(self):
|
|
||||||
ret = "\n#\n#\n# User-specific file contexts, generated via %s\n" % sys.argv[0]
|
|
||||||
ret += "# edit %s to change file_context\n#\n#\n" % self.getUsersFile()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def getUsers(self):
|
|
||||||
users=""
|
|
||||||
rc = commands.getstatusoutput('grep "^user" %s' % self.getSystemUsersFile())
|
|
||||||
if rc[0] == 0:
|
|
||||||
users+=rc[1]+"\n"
|
|
||||||
rc = commands.getstatusoutput("grep ^user %s" % self.getUsersFile())
|
|
||||||
if rc[0] == 0:
|
|
||||||
users+=rc[1]
|
|
||||||
udict = {}
|
|
||||||
prefs = {}
|
|
||||||
if users != "":
|
|
||||||
ulist = users.split("\n")
|
|
||||||
for u in ulist:
|
|
||||||
user = u.split()
|
|
||||||
try:
|
|
||||||
if len(user)==0 or user[1] == "user_u" or user[1] == "system_u":
|
|
||||||
continue
|
|
||||||
# !!! chooses first role in the list to use in the file context !!!
|
|
||||||
role = user[3]
|
|
||||||
if role == "{":
|
|
||||||
role = user[4]
|
|
||||||
role = role.split("_r")[0]
|
|
||||||
home = pwd.getpwnam(user[1])[5]
|
|
||||||
if home == "/":
|
|
||||||
continue
|
|
||||||
prefs = {}
|
|
||||||
prefs["role"] = role
|
|
||||||
prefs["home"] = home
|
|
||||||
udict[user[1]] = prefs
|
|
||||||
except KeyError:
|
|
||||||
sys.stderr.write("The user \"%s\" is not present in the passwd file, skipping...\n" % user[1])
|
|
||||||
return udict
|
|
||||||
|
|
||||||
def getHomeDirContext(self, user, home, role):
|
|
||||||
ret="\n\n#\n# Context for user %s\n#\n\n" % user
|
|
||||||
rc=commands.getstatusoutput("grep '^HOME_DIR' %s | sed -e 's|HOME_DIR|%s|' -e 's/ROLE/%s/' -e 's/system_u/%s/'" % (self.getHomeDirTemplate(), home, role, user))
|
|
||||||
return ret + rc[1] + "\n"
|
|
||||||
|
|
||||||
def genHomeDirContext(self):
|
|
||||||
users = self.getUsers()
|
|
||||||
ret=""
|
|
||||||
# Fill in HOME and ROLE for users that are defined
|
|
||||||
for u in users.keys():
|
|
||||||
ret += self.getHomeDirContext (u, users[u]["home"], users[u]["role"])
|
|
||||||
return ret+"\n"
|
|
||||||
|
|
||||||
def checkExists(self, home):
|
|
||||||
if commands.getstatusoutput("grep -E '^%s[^[:alnum:]_-]' %s" % (home, self.getFileContextFile()))[0] == 0:
|
|
||||||
return 0
|
|
||||||
#this works by grepping the file_contexts for
|
|
||||||
# 1. ^/ makes sure this is not a comment
|
|
||||||
# 2. prints only the regex in the first column first cut on \t then on space
|
|
||||||
rc=commands.getstatusoutput("grep \"^/\" %s | cut -f 1 | cut -f 1 -d \" \" " % self.getFileContextFile() )
|
|
||||||
if rc[0] == 0:
|
|
||||||
prefix_regex = rc[1].split("\n")
|
|
||||||
else:
|
|
||||||
sys.stderr.write("%s\n" % rc[1])
|
|
||||||
sys.stderr.write("You do not have access to grep/cut/the file contexts\n")
|
|
||||||
sys.stderr.flush()
|
|
||||||
exists=1
|
|
||||||
for regex in prefix_regex:
|
|
||||||
#match a trailing (/*)? which is actually a bug in rpc_pipefs
|
|
||||||
regex = re.sub("\(/\*\)\?$", "", regex)
|
|
||||||
#match a trailing .+
|
|
||||||
regex = re.sub("\.+$", "", regex)
|
|
||||||
#match a trailing .*
|
|
||||||
regex = re.sub("\.\*$", "", regex)
|
|
||||||
#strip a (/.*)? which matches anything trailing to a /*$ which matches trailing /'s
|
|
||||||
regex = re.sub("\(\/\.\*\)\?", "", regex)
|
|
||||||
regex = regex + "/*$"
|
|
||||||
if re.search(regex, home, 0):
|
|
||||||
exists = 0
|
|
||||||
break
|
|
||||||
if exists == 1:
|
|
||||||
return 1
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def getHomeDirs(self):
|
|
||||||
homedirs = []
|
|
||||||
homedirs = homedirs + getDefaultHomeDir()
|
|
||||||
starting_uid=getStartingUID()
|
|
||||||
if self.usepwd==0:
|
|
||||||
return homedirs
|
|
||||||
ulist = pwd.getpwall()
|
|
||||||
for u in ulist:
|
|
||||||
if u[2] >= starting_uid and \
|
|
||||||
not u[6] in EXCLUDE_LOGINS and \
|
|
||||||
u[5] != "/" and \
|
|
||||||
string.count(u[5], "/") > 1:
|
|
||||||
homedir = u[5][:string.rfind(u[5], "/")]
|
|
||||||
if not homedir in homedirs:
|
|
||||||
if self.checkExists(homedir)==0:
|
|
||||||
warning("%s is already defined in %s,\n%s will not create a new context." % (homedir, self.getFileContextFile(), sys.argv[0]))
|
|
||||||
else:
|
|
||||||
homedirs.append(homedir)
|
|
||||||
|
|
||||||
homedirs.sort()
|
|
||||||
return homedirs
|
|
||||||
|
|
||||||
def genoutput(self):
|
|
||||||
ret= self.heading()
|
|
||||||
for h in self.getHomeDirs():
|
|
||||||
ret += self.getHomeDirContext ("user_u" , h+'/[^/]*', "user")
|
|
||||||
ret += self.getHomeRootContext(h)
|
|
||||||
ret += self.genHomeDirContext()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def printout(self):
|
|
||||||
print self.genoutput()
|
|
||||||
|
|
||||||
def write(self):
|
|
||||||
try:
|
|
||||||
fd = open(self.getFileContextDir()+"/file_contexts.homedirs", "w")
|
|
||||||
fd.write(self.genoutput())
|
|
||||||
fd.close()
|
|
||||||
except IOError, error:
|
|
||||||
sys.stderr.write("%s: %s\n" % ( sys.argv[0], error ))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# This script will generate home dir file context
|
|
||||||
# based off the homedir_template file, entries in the password file, and
|
|
||||||
#
|
|
||||||
try:
|
|
||||||
usepwd=1
|
|
||||||
directory="/etc/selinux"
|
|
||||||
type=None
|
|
||||||
gopts, cmds = getopt.getopt(sys.argv[1:], 'nd:t:', ['help',
|
|
||||||
'type=',
|
|
||||||
'nopasswd',
|
|
||||||
'dir='])
|
|
||||||
for o,a in gopts:
|
|
||||||
if o == '--type' or o == "-t":
|
|
||||||
type=a
|
|
||||||
if o == '--nopasswd' or o == "-n":
|
|
||||||
usepwd=0
|
|
||||||
if o == '--dir' or o == "-d":
|
|
||||||
directory=a
|
|
||||||
if o == '--help':
|
|
||||||
usage()
|
|
||||||
|
|
||||||
|
|
||||||
if type==None:
|
|
||||||
type=getSELinuxType(directory)
|
|
||||||
|
|
||||||
if len(cmds) == 2:
|
|
||||||
oldgenhomedircon(cmds[0], cmds[1])
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
if len(cmds) != 0:
|
|
||||||
usage()
|
|
||||||
selconf=selinuxConfig(directory, type, usepwd)
|
|
||||||
selconf.write()
|
|
||||||
|
|
||||||
except getopt.error, error:
|
|
||||||
errorExit(string.join("Options Error ", error))
|
|
||||||
except ValueError, error:
|
|
||||||
errorExit(string.join("ValueError ", error))
|
|
||||||
except IndexError, error:
|
|
||||||
errorExit("IndexError")
|
|
@ -1,163 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
# Author: Chris PeBenito <cpebenito@tresys.com>
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006 Tresys Technology, LLC
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, version 2.
|
|
||||||
|
|
||||||
import sys,string,getopt,re
|
|
||||||
|
|
||||||
NETPORT = re.compile("^network_port\(\s*\w+\s*(\s*,\s*\w+\s*,\s*\w+\s*,\s*\w+\s*)+\s*\)\s*(#|$)")
|
|
||||||
|
|
||||||
DEFAULT_INPUT_PACKET = "server_packet_t"
|
|
||||||
DEFAULT_OUTPUT_PACKET = "client_packet_t"
|
|
||||||
DEFAULT_MCS = "s0"
|
|
||||||
DEFAULT_MLS = "s0"
|
|
||||||
|
|
||||||
PACKET_INPUT = "_server_packet_t"
|
|
||||||
PACKET_OUTPUT = "_client_packet_t"
|
|
||||||
|
|
||||||
class Port:
|
|
||||||
def __init__(self, proto, num, mls_sens, mcs_cats=""):
|
|
||||||
# protocol of the port
|
|
||||||
self.proto = proto
|
|
||||||
|
|
||||||
# port number
|
|
||||||
self.num = num
|
|
||||||
|
|
||||||
# MLS sensitivity
|
|
||||||
self.mls_sens = mls_sens
|
|
||||||
|
|
||||||
# MCS categories
|
|
||||||
# not currently supported, so we always get s0
|
|
||||||
self.mcs_cats = DEFAULT_MCS
|
|
||||||
|
|
||||||
class Packet:
|
|
||||||
def __init__(self, prefix, ports):
|
|
||||||
# prefix
|
|
||||||
self.prefix = prefix
|
|
||||||
|
|
||||||
# A list of Ports
|
|
||||||
self.ports = ports
|
|
||||||
|
|
||||||
def print_input_rules(packets,mls,mcs):
|
|
||||||
line = "base -A selinux_new_input -j SECMARK --selctx system_u:object_r:"+DEFAULT_INPUT_PACKET
|
|
||||||
if mls:
|
|
||||||
line += ":"+DEFAULT_MLS
|
|
||||||
elif mcs:
|
|
||||||
line += ":"+DEFAULT_MCS
|
|
||||||
|
|
||||||
print line
|
|
||||||
|
|
||||||
for i in packets:
|
|
||||||
for j in i.ports:
|
|
||||||
line="base -A selinux_new_input -p "+j.proto+" --dport "+j.num+" -j SECMARK --selctx system_u:object_r:"+i.prefix+PACKET_INPUT
|
|
||||||
if mls:
|
|
||||||
line += ":"+j.mls_sens
|
|
||||||
elif mcs:
|
|
||||||
line += ":"+j.mcs_cats
|
|
||||||
print line
|
|
||||||
|
|
||||||
print "post -A selinux_new_input -j CONNSECMARK --save"
|
|
||||||
print "post -A selinux_new_input -j RETURN"
|
|
||||||
|
|
||||||
def print_output_rules(packets,mls,mcs):
|
|
||||||
line = "base -A selinux_new_output -j SECMARK --selctx system_u:object_r:"+DEFAULT_OUTPUT_PACKET
|
|
||||||
if mls:
|
|
||||||
line += ":"+DEFAULT_MLS
|
|
||||||
elif mcs:
|
|
||||||
line += ":"+DEFAULT_MCS
|
|
||||||
print line
|
|
||||||
|
|
||||||
for i in packets:
|
|
||||||
for j in i.ports:
|
|
||||||
line = "base -A selinux_new_output -p "+j.proto+" --dport "+j.num+" -j SECMARK --selctx system_u:object_r:"+i.prefix+PACKET_OUTPUT
|
|
||||||
if mls:
|
|
||||||
line += ":"+j.mls_sens
|
|
||||||
elif mcs:
|
|
||||||
line += ":"+j.mcs_cats
|
|
||||||
print line
|
|
||||||
|
|
||||||
print "post -A selinux_new_output -j CONNSECMARK --save"
|
|
||||||
print "post -A selinux_new_output -j RETURN"
|
|
||||||
|
|
||||||
def parse_corenet(file_name):
|
|
||||||
packets = []
|
|
||||||
|
|
||||||
corenet_te_in = open(file_name, "r")
|
|
||||||
|
|
||||||
while True:
|
|
||||||
corenet_line = corenet_te_in.readline()
|
|
||||||
|
|
||||||
# If EOF has been reached:
|
|
||||||
if not corenet_line:
|
|
||||||
break
|
|
||||||
|
|
||||||
if NETPORT.match(corenet_line):
|
|
||||||
corenet_line = corenet_line.strip();
|
|
||||||
|
|
||||||
# parse out the parameters
|
|
||||||
openparen = string.find(corenet_line,'(')+1
|
|
||||||
closeparen = string.find(corenet_line,')',openparen)
|
|
||||||
parms = re.split('\W+',corenet_line[openparen:closeparen])
|
|
||||||
name = parms[0]
|
|
||||||
del parms[0];
|
|
||||||
|
|
||||||
ports = []
|
|
||||||
while len(parms) > 0:
|
|
||||||
# add a port combination.
|
|
||||||
ports.append(Port(parms[0],parms[1],parms[2]))
|
|
||||||
del parms[:3]
|
|
||||||
|
|
||||||
packets.append(Packet(name,ports))
|
|
||||||
|
|
||||||
corenet_te_in.close()
|
|
||||||
|
|
||||||
return packets
|
|
||||||
|
|
||||||
def print_netfilter_config(packets,mls,mcs):
|
|
||||||
print "pre *mangle"
|
|
||||||
print "pre :PREROUTING ACCEPT [0:0]"
|
|
||||||
print "pre :INPUT ACCEPT [0:0]"
|
|
||||||
print "pre :FORWARD ACCEPT [0:0]"
|
|
||||||
print "pre :OUTPUT ACCEPT [0:0]"
|
|
||||||
print "pre :POSTROUTING ACCEPT [0:0]"
|
|
||||||
print "pre :selinux_input - [0:0]"
|
|
||||||
print "pre :selinux_output - [0:0]"
|
|
||||||
print "pre :selinux_new_input - [0:0]"
|
|
||||||
print "pre :selinux_new_output - [0:0]"
|
|
||||||
print "pre -A INPUT -j selinux_input"
|
|
||||||
print "pre -A OUTPUT -j selinux_output"
|
|
||||||
print "pre -A selinux_input -m state --state NEW -j selinux_new_input"
|
|
||||||
print "pre -A selinux_input -m state --state RELATED,ESTABLISHED -j CONNSECMARK --restore"
|
|
||||||
print "pre -A selinux_output -m state --state NEW -j selinux_new_output"
|
|
||||||
print "pre -A selinux_output -m state --state RELATED,ESTABLISHED -j CONNSECMARK --restore"
|
|
||||||
print_input_rules(packets,mls,mcs)
|
|
||||||
print_output_rules(packets,mls,mcs)
|
|
||||||
print "post COMMIT"
|
|
||||||
|
|
||||||
mls = False
|
|
||||||
mcs = False
|
|
||||||
|
|
||||||
try:
|
|
||||||
opts, paths = getopt.getopt(sys.argv[1:],'mc',['mls','mcs'])
|
|
||||||
except getopt.GetoptError, error:
|
|
||||||
print "Invalid options."
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
for o, a in opts:
|
|
||||||
if o in ("-c","--mcs"):
|
|
||||||
mcs = True
|
|
||||||
if o in ("-m","--mls"):
|
|
||||||
mls = True
|
|
||||||
|
|
||||||
if len(paths) == 0:
|
|
||||||
sys.stderr.write("Need a path for corenetwork.te.in!\n")
|
|
||||||
sys.exit(1)
|
|
||||||
elif len(paths) > 1:
|
|
||||||
sys.stderr.write("Ignoring extra specified paths\n")
|
|
||||||
|
|
||||||
packets=parse_corenet(paths[0])
|
|
||||||
print_netfilter_config(packets,mls,mcs)
|
|
@ -1,13 +0,0 @@
|
|||||||
#n
|
|
||||||
# print out type and attribute declarations that
|
|
||||||
# are not inside require and optional blocks.
|
|
||||||
|
|
||||||
/require \{/,/} # end require/b nextline
|
|
||||||
/optional \{/,/} # end optional/b nextline
|
|
||||||
|
|
||||||
/^[[:blank:]]*(attribute|type(alias)?|bool) /{
|
|
||||||
s/^[[:blank:]]+//
|
|
||||||
p
|
|
||||||
}
|
|
||||||
|
|
||||||
:nextline
|
|
@ -1 +0,0 @@
|
|||||||
ifdef(`__if_error',`m4exit(1)')
|
|
@ -1,364 +0,0 @@
|
|||||||
"""PyPlate : a simple Python-based templating program
|
|
||||||
|
|
||||||
PyPlate parses a file and replaces directives (in double square brackets [[ ... ]])
|
|
||||||
by various means using a given dictionary of variables. Arbitrary Python code
|
|
||||||
can be run inside many of the directives, making this system highly flexible.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
# Load and parse template file
|
|
||||||
template = pyplate.Template("output") (filename or string)
|
|
||||||
# Execute it with a dictionary of variables
|
|
||||||
template.execute_file(output_stream, locals())
|
|
||||||
|
|
||||||
PyPlate defines the following directives:
|
|
||||||
[[...]] evaluate the arbitrary Python expression and insert the
|
|
||||||
result into the output
|
|
||||||
|
|
||||||
[[# ... #]] comment.
|
|
||||||
|
|
||||||
[[exec ...]] execute arbitrary Python code in the sandbox namespace
|
|
||||||
|
|
||||||
[[if ...]] conditional expressions with usual Python semantics
|
|
||||||
[[elif ...]]
|
|
||||||
[[else]]
|
|
||||||
[[end]]
|
|
||||||
|
|
||||||
[[for ... in ...]] for-loop with usual Python semantics
|
|
||||||
[[end]]
|
|
||||||
|
|
||||||
[[def ...(...)]] define a "function" out of other templating elements
|
|
||||||
[[end]]
|
|
||||||
|
|
||||||
[[call ...]] call a templating function (not a regular Python function)
|
|
||||||
"""
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (C) 2002 Michael Droettboom
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# 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, write to the Free Software
|
|
||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
|
||||||
|
|
||||||
from __future__ import nested_scopes
|
|
||||||
import sys, string, re, cStringIO
|
|
||||||
|
|
||||||
re_directive = re.compile("\[\[(.*)\]\]")
|
|
||||||
re_for_loop = re.compile("for (.*) in (.*)")
|
|
||||||
re_if = re.compile("if (.*)")
|
|
||||||
re_elif = re.compile("elif (.*)")
|
|
||||||
re_def = re.compile("def (.*?)\((.*)\)")
|
|
||||||
re_call = re.compile("call (.*?)\((.*)\)")
|
|
||||||
re_exec = re.compile("exec (.*)")
|
|
||||||
re_comment = re.compile("#(.*)#")
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
# Template parser
|
|
||||||
class ParserException(Exception):
|
|
||||||
def __init__(self, lineno, s):
|
|
||||||
Exception.__init__(self, "line %d: %s" % (lineno, s))
|
|
||||||
|
|
||||||
class Template:
|
|
||||||
def __init__(self, filename=None):
|
|
||||||
if filename != None:
|
|
||||||
try:
|
|
||||||
self.parse_file(filename)
|
|
||||||
except:
|
|
||||||
self.parse_string(filename)
|
|
||||||
|
|
||||||
def parse_file(self, filename):
|
|
||||||
file = open(filename, 'r')
|
|
||||||
self.parse(file)
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
def parse_string(self, template):
|
|
||||||
file = cStringIO.StringIO(template)
|
|
||||||
self.parse(file)
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
def parse(self, file):
|
|
||||||
self.file = file
|
|
||||||
self.line = self.file.read()
|
|
||||||
self.lineno = 0
|
|
||||||
self.functions = {}
|
|
||||||
self.tree = TopLevelTemplateNode(self)
|
|
||||||
|
|
||||||
def parser_get(self):
|
|
||||||
if self.line == '':
|
|
||||||
return None
|
|
||||||
return self.line
|
|
||||||
|
|
||||||
def parser_eat(self, chars):
|
|
||||||
self.lineno = self.lineno + self.line[:chars].count("\n")
|
|
||||||
self.line = self.line[chars:]
|
|
||||||
|
|
||||||
def parser_exception(self, s):
|
|
||||||
raise ParserException(self.lineno, s)
|
|
||||||
|
|
||||||
def execute_file(self, filename, data):
|
|
||||||
file = open(filename, 'w')
|
|
||||||
self.execute(file, data)
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
def execute_string(self, data):
|
|
||||||
s = cStringIO.StringIO()
|
|
||||||
self.execute(s, data)
|
|
||||||
return s.getvalue()
|
|
||||||
|
|
||||||
def execute_stdout(self, data):
|
|
||||||
self.execute(sys.stdout, data)
|
|
||||||
|
|
||||||
def execute(self, stream=sys.stdout, data={}):
|
|
||||||
self.tree.execute(stream, data)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return repr(self.tree)
|
|
||||||
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
# NODES
|
|
||||||
class TemplateNode:
|
|
||||||
def __init__(self, parent, s):
|
|
||||||
self.parent = parent
|
|
||||||
self.s = s
|
|
||||||
self.node_list = []
|
|
||||||
while 1:
|
|
||||||
new_node = TemplateNodeFactory(parent)
|
|
||||||
if self.add_node(new_node):
|
|
||||||
break
|
|
||||||
|
|
||||||
def add_node(self, node):
|
|
||||||
if node == 'end':
|
|
||||||
return 1
|
|
||||||
elif node != None:
|
|
||||||
self.node_list.append(node)
|
|
||||||
else:
|
|
||||||
raise self.parent.parser_exception(
|
|
||||||
"[[%s]] does not have a matching [[end]]" % self.s)
|
|
||||||
|
|
||||||
def execute(self, stream, data):
|
|
||||||
for node in self.node_list:
|
|
||||||
node.execute(stream, data)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
r = "<" + self.__class__.__name__ + " "
|
|
||||||
for i in self.node_list:
|
|
||||||
r = r + repr(i)
|
|
||||||
r = r + ">"
|
|
||||||
return r
|
|
||||||
|
|
||||||
class TopLevelTemplateNode(TemplateNode):
|
|
||||||
def __init__(self, parent):
|
|
||||||
TemplateNode.__init__(self, parent, '')
|
|
||||||
|
|
||||||
def add_node(self, node):
|
|
||||||
if node != None:
|
|
||||||
self.node_list.append(node)
|
|
||||||
else:
|
|
||||||
return 1
|
|
||||||
|
|
||||||
class ForTemplateNode(TemplateNode):
|
|
||||||
def __init__(self, parent, s):
|
|
||||||
TemplateNode.__init__(self, parent, s)
|
|
||||||
match = re_for_loop.match(s)
|
|
||||||
if match == None:
|
|
||||||
raise self.parent.parser_exception(
|
|
||||||
"[[%s]] is not a valid for-loop expression" % self.s)
|
|
||||||
else:
|
|
||||||
self.vars_temp = match.group(1).split(",")
|
|
||||||
self.vars = []
|
|
||||||
for v in self.vars_temp:
|
|
||||||
self.vars.append(v.strip())
|
|
||||||
#print self.vars
|
|
||||||
self.expression = match.group(2)
|
|
||||||
|
|
||||||
def execute(self, stream, data):
|
|
||||||
remember_vars = {}
|
|
||||||
for var in self.vars:
|
|
||||||
if data.has_key(var):
|
|
||||||
remember_vars[var] = data[var]
|
|
||||||
for list in eval(self.expression, globals(), data):
|
|
||||||
if is_sequence(list):
|
|
||||||
for index, value in enumerate(list):
|
|
||||||
data[self.vars[index]] = value
|
|
||||||
else:
|
|
||||||
data[self.vars[0]] = list
|
|
||||||
TemplateNode.execute(self, stream, data)
|
|
||||||
for key, value in remember_vars.items():
|
|
||||||
data[key] = value
|
|
||||||
|
|
||||||
class IfTemplateNode(TemplateNode):
|
|
||||||
def __init__(self, parent, s):
|
|
||||||
self.else_node = None
|
|
||||||
TemplateNode.__init__(self, parent, s)
|
|
||||||
match = re_if.match(s)
|
|
||||||
if match == None:
|
|
||||||
raise self.parent.parser_exception(
|
|
||||||
"[[%s]] is not a valid if expression" % self.s)
|
|
||||||
else:
|
|
||||||
self.expression = match.group(1)
|
|
||||||
|
|
||||||
def add_node(self, node):
|
|
||||||
if node == 'end':
|
|
||||||
return 1
|
|
||||||
elif isinstance(node, ElseTemplateNode):
|
|
||||||
self.else_node = node
|
|
||||||
return 1
|
|
||||||
elif isinstance(node, ElifTemplateNode):
|
|
||||||
self.else_node = node
|
|
||||||
return 1
|
|
||||||
elif node != None:
|
|
||||||
self.node_list.append(node)
|
|
||||||
else:
|
|
||||||
raise self.parent.parser_exception(
|
|
||||||
"[[%s]] does not have a matching [[end]]" % self.s)
|
|
||||||
|
|
||||||
def execute(self, stream, data):
|
|
||||||
if eval(self.expression, globals(), data):
|
|
||||||
TemplateNode.execute(self, stream, data)
|
|
||||||
elif self.else_node != None:
|
|
||||||
self.else_node.execute(stream, data)
|
|
||||||
|
|
||||||
class ElifTemplateNode(IfTemplateNode):
|
|
||||||
def __init__(self, parent, s):
|
|
||||||
self.else_node = None
|
|
||||||
TemplateNode.__init__(self, parent, s)
|
|
||||||
match = re_elif.match(s)
|
|
||||||
if match == None:
|
|
||||||
self.parent.parser_exception(
|
|
||||||
"[[%s]] is not a valid elif expression" % self.s)
|
|
||||||
else:
|
|
||||||
self.expression = match.group(1)
|
|
||||||
|
|
||||||
class ElseTemplateNode(TemplateNode):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class FunctionTemplateNode(TemplateNode):
|
|
||||||
def __init__(self, parent, s):
|
|
||||||
TemplateNode.__init__(self, parent, s)
|
|
||||||
match = re_def.match(s)
|
|
||||||
if match == None:
|
|
||||||
self.parent.parser_exception(
|
|
||||||
"[[%s]] is not a valid function definition" % self.s)
|
|
||||||
self.function_name = match.group(1)
|
|
||||||
self.vars_temp = match.group(2).split(",")
|
|
||||||
self.vars = []
|
|
||||||
for v in self.vars_temp:
|
|
||||||
self.vars.append(v.strip())
|
|
||||||
#print self.vars
|
|
||||||
self.parent.functions[self.function_name] = self
|
|
||||||
|
|
||||||
def execute(self, stream, data):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def call(self, args, stream, data):
|
|
||||||
remember_vars = {}
|
|
||||||
for index, var in enumerate(self.vars):
|
|
||||||
if data.has_key(var):
|
|
||||||
remember_vars[var] = data[var]
|
|
||||||
data[var] = args[index]
|
|
||||||
TemplateNode.execute(self, stream, data)
|
|
||||||
for key, value in remember_vars.items():
|
|
||||||
data[key] = value
|
|
||||||
|
|
||||||
class LeafTemplateNode(TemplateNode):
|
|
||||||
def __init__(self, parent, s):
|
|
||||||
self.parent = parent
|
|
||||||
self.s = s
|
|
||||||
|
|
||||||
def execute(self, stream, data):
|
|
||||||
stream.write(self.s)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<" + self.__class__.__name__ + ">"
|
|
||||||
|
|
||||||
class CommentTemplateNode(LeafTemplateNode):
|
|
||||||
def execute(self, stream, data):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class ExpressionTemplateNode(LeafTemplateNode):
|
|
||||||
def execute(self, stream, data):
|
|
||||||
stream.write(str(eval(self.s, globals(), data)))
|
|
||||||
|
|
||||||
class ExecTemplateNode(LeafTemplateNode):
|
|
||||||
def __init__(self, parent, s):
|
|
||||||
LeafTemplateNode.__init__(self, parent, s)
|
|
||||||
match = re_exec.match(s)
|
|
||||||
if match == None:
|
|
||||||
self.parent.parser_exception(
|
|
||||||
"[[%s]] is not a valid statement" % self.s)
|
|
||||||
self.s = match.group(1)
|
|
||||||
|
|
||||||
def execute(self, stream, data):
|
|
||||||
exec(self.s, globals(), data)
|
|
||||||
pass
|
|
||||||
|
|
||||||
class CallTemplateNode(LeafTemplateNode):
|
|
||||||
def __init__(self, parent, s):
|
|
||||||
LeafTemplateNode.__init__(self, parent, s)
|
|
||||||
match = re_call.match(s)
|
|
||||||
if match == None:
|
|
||||||
self.parent.parser_exception(
|
|
||||||
"[[%s]] is not a valid function call" % self.s)
|
|
||||||
self.function_name = match.group(1)
|
|
||||||
self.vars = "(" + match.group(2).strip() + ",)"
|
|
||||||
|
|
||||||
def execute(self, stream, data):
|
|
||||||
self.parent.functions[self.function_name].call(
|
|
||||||
eval(self.vars, globals(), data), stream, data)
|
|
||||||
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
# Node factory
|
|
||||||
template_factory_type_map = {
|
|
||||||
'if' : IfTemplateNode,
|
|
||||||
'for' : ForTemplateNode,
|
|
||||||
'elif' : ElifTemplateNode,
|
|
||||||
'else' : ElseTemplateNode,
|
|
||||||
'def' : FunctionTemplateNode,
|
|
||||||
'call' : CallTemplateNode,
|
|
||||||
'exec' : ExecTemplateNode }
|
|
||||||
template_factory_types = template_factory_type_map.keys()
|
|
||||||
|
|
||||||
def TemplateNodeFactory(parent):
|
|
||||||
src = parent.parser_get()
|
|
||||||
|
|
||||||
if src == None:
|
|
||||||
return None
|
|
||||||
match = re_directive.search(src)
|
|
||||||
if match == None:
|
|
||||||
parent.parser_eat(len(src))
|
|
||||||
return LeafTemplateNode(parent, src)
|
|
||||||
elif src == '' or match.start() != 0:
|
|
||||||
parent.parser_eat(match.start())
|
|
||||||
return LeafTemplateNode(parent, src[:match.start()])
|
|
||||||
else:
|
|
||||||
directive = match.group()[2:-2].strip()
|
|
||||||
parent.parser_eat(match.end())
|
|
||||||
if directive == 'end':
|
|
||||||
return 'end'
|
|
||||||
elif re_comment.match(directive):
|
|
||||||
return CommentTemplateNode(parent, directive)
|
|
||||||
else:
|
|
||||||
for i in template_factory_types:
|
|
||||||
if directive[0:len(i)] == i:
|
|
||||||
return template_factory_type_map[i](parent, directive)
|
|
||||||
return ExpressionTemplateNode(parent, directive)
|
|
||||||
|
|
||||||
def is_sequence(object):
|
|
||||||
try:
|
|
||||||
test = object[0:0]
|
|
||||||
except:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
@ -1,847 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
# Author: Joshua Brindle <jbrindle@tresys.com>
|
|
||||||
# Caleb Case <ccase@tresys.com>
|
|
||||||
#
|
|
||||||
# Copyright (C) 2005 - 2006 Tresys Technology, LLC
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, version 2.
|
|
||||||
|
|
||||||
"""
|
|
||||||
This module generates configuration files and documentation from the
|
|
||||||
SELinux reference policy XML format.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import getopt
|
|
||||||
import pyplate
|
|
||||||
import os
|
|
||||||
import string
|
|
||||||
from xml.dom.minidom import parse, parseString
|
|
||||||
|
|
||||||
#modules enabled and disabled values
|
|
||||||
MOD_BASE = "base"
|
|
||||||
MOD_ENABLED = "module"
|
|
||||||
MOD_DISABLED = "off"
|
|
||||||
|
|
||||||
#booleans enabled and disabled values
|
|
||||||
BOOL_ENABLED = "true"
|
|
||||||
BOOL_DISABLED = "false"
|
|
||||||
|
|
||||||
#tunables enabled and disabled values
|
|
||||||
TUN_ENABLED = "true"
|
|
||||||
TUN_DISABLED = "false"
|
|
||||||
|
|
||||||
|
|
||||||
def read_policy_xml(filename):
|
|
||||||
"""
|
|
||||||
Takes in XML from a file and returns a parsed file.
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
xml_fh = open(filename)
|
|
||||||
except:
|
|
||||||
error("error opening " + filename)
|
|
||||||
|
|
||||||
try:
|
|
||||||
doc = parseString(xml_fh.read())
|
|
||||||
except:
|
|
||||||
xml_fh.close()
|
|
||||||
error("Error while parsing xml")
|
|
||||||
|
|
||||||
xml_fh.close()
|
|
||||||
return doc
|
|
||||||
|
|
||||||
def gen_booleans_conf(doc, file_name, namevalue_list):
|
|
||||||
"""
|
|
||||||
Generates the booleans configuration file using the XML provided and the
|
|
||||||
previous booleans configuration.
|
|
||||||
"""
|
|
||||||
|
|
||||||
for node in doc.getElementsByTagName("bool"):
|
|
||||||
for desc in node.getElementsByTagName("desc"):
|
|
||||||
bool_desc = format_txt_desc(desc)
|
|
||||||
s = string.split(bool_desc, "\n")
|
|
||||||
file_name.write("#\n")
|
|
||||||
for line in s:
|
|
||||||
file_name.write("# %s\n" % line)
|
|
||||||
|
|
||||||
bool_name = bool_val = None
|
|
||||||
for (name, value) in node.attributes.items():
|
|
||||||
if name == "name":
|
|
||||||
bool_name = value
|
|
||||||
elif name == "dftval":
|
|
||||||
bool_val = value
|
|
||||||
|
|
||||||
if [bool_name,BOOL_ENABLED] in namevalue_list:
|
|
||||||
bool_val = BOOL_ENABLED
|
|
||||||
elif [bool_name,BOOL_DISABLED] in namevalue_list:
|
|
||||||
bool_val = BOOL_DISABLED
|
|
||||||
|
|
||||||
if bool_name and bool_val:
|
|
||||||
file_name.write("%s = %s\n\n" % (bool_name, bool_val))
|
|
||||||
bool_name = bool_val = None
|
|
||||||
|
|
||||||
# tunables are currently implemented as booleans
|
|
||||||
for node in doc.getElementsByTagName("tunable"):
|
|
||||||
for desc in node.getElementsByTagName("desc"):
|
|
||||||
bool_desc = format_txt_desc(desc)
|
|
||||||
s = string.split(bool_desc, "\n")
|
|
||||||
file_name.write("#\n")
|
|
||||||
for line in s:
|
|
||||||
file_name.write("# %s\n" % line)
|
|
||||||
|
|
||||||
bool_name = bool_val = None
|
|
||||||
for (name, value) in node.attributes.items():
|
|
||||||
if name == "name":
|
|
||||||
bool_name = value
|
|
||||||
elif name == "dftval":
|
|
||||||
bool_val = value
|
|
||||||
|
|
||||||
if [bool_name,BOOL_ENABLED] in namevalue_list:
|
|
||||||
bool_val = BOOL_ENABLED
|
|
||||||
elif [bool_name,BOOL_DISABLED] in namevalue_list:
|
|
||||||
bool_val = BOOL_DISABLED
|
|
||||||
|
|
||||||
if bool_name and bool_val:
|
|
||||||
file_name.write("%s = %s\n\n" % (bool_name, bool_val))
|
|
||||||
bool_name = bool_val = None
|
|
||||||
|
|
||||||
def gen_module_conf(doc, file_name, namevalue_list):
|
|
||||||
"""
|
|
||||||
Generates the module configuration file using the XML provided and the
|
|
||||||
previous module configuration.
|
|
||||||
"""
|
|
||||||
# If file exists, preserve settings and modify if needed.
|
|
||||||
# Otherwise, create it.
|
|
||||||
|
|
||||||
file_name.write("#\n# This file contains a listing of available modules.\n")
|
|
||||||
file_name.write("# To prevent a module from being used in policy\n")
|
|
||||||
file_name.write("# creation, set the module name to \"%s\".\n#\n" % MOD_DISABLED)
|
|
||||||
file_name.write("# For monolithic policies, modules set to \"%s\" and \"%s\"\n" % (MOD_BASE, MOD_ENABLED))
|
|
||||||
file_name.write("# will be built into the policy.\n#\n")
|
|
||||||
file_name.write("# For modular policies, modules set to \"%s\" will be\n" % MOD_BASE)
|
|
||||||
file_name.write("# included in the base module. \"%s\" will be compiled\n" % MOD_ENABLED)
|
|
||||||
file_name.write("# as individual loadable modules.\n#\n\n")
|
|
||||||
|
|
||||||
# For required in [True,False] is present so that the requiered modules
|
|
||||||
# are at the top of the config file.
|
|
||||||
for required in [True,False]:
|
|
||||||
for node in doc.getElementsByTagName("module"):
|
|
||||||
mod_req = False
|
|
||||||
for req in node.getElementsByTagName("required"):
|
|
||||||
if req.getAttribute("val") == "true":
|
|
||||||
mod_req = True
|
|
||||||
|
|
||||||
# Skip if we arnt working on the right set of modules.
|
|
||||||
if mod_req and not required or not mod_req and required:
|
|
||||||
continue
|
|
||||||
|
|
||||||
|
|
||||||
mod_name = mod_layer = None
|
|
||||||
|
|
||||||
mod_name = node.getAttribute("name")
|
|
||||||
mod_layer = node.parentNode.getAttribute("name")
|
|
||||||
|
|
||||||
if mod_name and mod_layer:
|
|
||||||
file_name.write("# Layer: %s\n# Module: %s\n" % (mod_layer,mod_name))
|
|
||||||
if required:
|
|
||||||
file_name.write("# Required in base\n")
|
|
||||||
file_name.write("#\n")
|
|
||||||
|
|
||||||
for desc in node.getElementsByTagName("summary"):
|
|
||||||
if not desc.parentNode == node:
|
|
||||||
continue
|
|
||||||
s = string.split(format_txt_desc(desc), "\n")
|
|
||||||
for line in s:
|
|
||||||
file_name.write("# %s\n" % line)
|
|
||||||
|
|
||||||
# If the module is set as disabled.
|
|
||||||
if [mod_name, MOD_DISABLED] in namevalue_list:
|
|
||||||
file_name.write("%s = %s\n\n" % (mod_name, MOD_DISABLED))
|
|
||||||
# If the module is set as enabled.
|
|
||||||
elif [mod_name, MOD_ENABLED] in namevalue_list:
|
|
||||||
file_name.write("%s = %s\n\n" % (mod_name, MOD_ENABLED))
|
|
||||||
# If the module is set as base.
|
|
||||||
elif [mod_name, MOD_BASE] in namevalue_list:
|
|
||||||
file_name.write("%s = %s\n\n" % (mod_name, MOD_BASE))
|
|
||||||
# If the module is a new module.
|
|
||||||
else:
|
|
||||||
# Set the module to base if it is marked as required.
|
|
||||||
if mod_req:
|
|
||||||
file_name.write("%s = %s\n\n" % (mod_name, MOD_BASE))
|
|
||||||
# Set the module to enabled if it is not required.
|
|
||||||
else:
|
|
||||||
file_name.write("%s = %s\n\n" % (mod_name, MOD_ENABLED))
|
|
||||||
|
|
||||||
def get_conf(conf):
|
|
||||||
"""
|
|
||||||
Returns a list of [name, value] pairs from a config file with the format
|
|
||||||
name = value
|
|
||||||
"""
|
|
||||||
|
|
||||||
conf_lines = conf.readlines()
|
|
||||||
|
|
||||||
namevalue_list = []
|
|
||||||
for i in range(0,len(conf_lines)):
|
|
||||||
line = conf_lines[i]
|
|
||||||
if line.strip() != '' and line.strip()[0] != "#":
|
|
||||||
namevalue = line.strip().split("=")
|
|
||||||
if len(namevalue) != 2:
|
|
||||||
warning("line %d: \"%s\" is not a valid line, skipping"\
|
|
||||||
% (i, line.strip()))
|
|
||||||
continue
|
|
||||||
|
|
||||||
namevalue[0] = namevalue[0].strip()
|
|
||||||
if len(namevalue[0].split()) > 1:
|
|
||||||
warning("line %d: \"%s\" is not a valid line, skipping"\
|
|
||||||
% (i, line.strip()))
|
|
||||||
continue
|
|
||||||
|
|
||||||
namevalue[1] = namevalue[1].strip()
|
|
||||||
if len(namevalue[1].split()) > 1:
|
|
||||||
warning("line %d: \"%s\" is not a valid line, skipping"\
|
|
||||||
% (i, line.strip()))
|
|
||||||
continue
|
|
||||||
|
|
||||||
namevalue_list.append(namevalue)
|
|
||||||
|
|
||||||
return namevalue_list
|
|
||||||
|
|
||||||
def first_cmp(a, b):
|
|
||||||
"""
|
|
||||||
Compares the two first elements of a list instead of the entire list.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return cmp(a[0], b[0])
|
|
||||||
|
|
||||||
def int_cmp(a, b):
|
|
||||||
"""
|
|
||||||
Compares two interfaces.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return cmp(a["interface_name"], b["interface_name"])
|
|
||||||
|
|
||||||
def temp_cmp(a, b):
|
|
||||||
"""
|
|
||||||
Compares two templates.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return cmp(a["template_name"], b["template_name"])
|
|
||||||
|
|
||||||
def tun_cmp(a, b):
|
|
||||||
"""
|
|
||||||
Compares two tunables.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return cmp(a["tun_name"], b["tun_name"])
|
|
||||||
def bool_cmp(a, b):
|
|
||||||
"""
|
|
||||||
Compares two booleans.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return cmp(a["bool_name"], b["bool_name"])
|
|
||||||
|
|
||||||
def gen_doc_menu(mod_layer, module_list):
|
|
||||||
"""
|
|
||||||
Generates the HTML document menu.
|
|
||||||
"""
|
|
||||||
|
|
||||||
menu = []
|
|
||||||
for layer, value in module_list.iteritems():
|
|
||||||
cur_menu = (layer, [])
|
|
||||||
menu.append(cur_menu)
|
|
||||||
if layer != mod_layer and mod_layer != None:
|
|
||||||
continue
|
|
||||||
#we are in our layer so fill in the other modules or we want them all
|
|
||||||
for mod, desc in value.iteritems():
|
|
||||||
cur_menu[1].append((mod, desc))
|
|
||||||
|
|
||||||
menu.sort(first_cmp)
|
|
||||||
for x in menu:
|
|
||||||
x[1].sort(first_cmp)
|
|
||||||
return menu
|
|
||||||
|
|
||||||
def format_html_desc(node):
|
|
||||||
"""
|
|
||||||
Formats a XML node into a HTML format.
|
|
||||||
"""
|
|
||||||
|
|
||||||
desc_buf = ''
|
|
||||||
for desc in node.childNodes:
|
|
||||||
if desc.nodeName == "#text":
|
|
||||||
if desc.data is not '':
|
|
||||||
if desc.parentNode.nodeName != "p":
|
|
||||||
desc_buf += "<p>" + desc.data + "</p>"
|
|
||||||
else:
|
|
||||||
desc_buf += desc.data
|
|
||||||
else:
|
|
||||||
desc_buf += "<" + desc.nodeName + ">" \
|
|
||||||
+ format_html_desc(desc) \
|
|
||||||
+ "</" + desc.nodeName +">"
|
|
||||||
|
|
||||||
return desc_buf
|
|
||||||
|
|
||||||
def format_txt_desc(node):
|
|
||||||
"""
|
|
||||||
Formats a XML node into a plain text format.
|
|
||||||
"""
|
|
||||||
|
|
||||||
desc_buf = ''
|
|
||||||
for desc in node.childNodes:
|
|
||||||
if desc.nodeName == "#text":
|
|
||||||
desc_buf += desc.data + "\n"
|
|
||||||
elif desc.nodeName == "p":
|
|
||||||
desc_buf += desc.firstChild.data + "\n"
|
|
||||||
for chld in desc.childNodes:
|
|
||||||
if chld.nodeName == "ul":
|
|
||||||
desc_buf += "\n"
|
|
||||||
for li in chld.getElementsByTagName("li"):
|
|
||||||
desc_buf += "\t -" + li.firstChild.data + "\n"
|
|
||||||
|
|
||||||
return desc_buf.strip() + "\n"
|
|
||||||
|
|
||||||
def gen_docs(doc, working_dir, templatedir):
|
|
||||||
"""
|
|
||||||
Generates all the documentation.
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
#get the template data ahead of time so we don't reopen them over and over
|
|
||||||
bodyfile = open(templatedir + "/header.html", "r")
|
|
||||||
bodydata = bodyfile.read()
|
|
||||||
bodyfile.close()
|
|
||||||
intfile = open(templatedir + "/interface.html", "r")
|
|
||||||
intdata = intfile.read()
|
|
||||||
intfile.close()
|
|
||||||
templatefile = open(templatedir + "/template.html", "r")
|
|
||||||
templatedata = templatefile.read()
|
|
||||||
templatefile.close()
|
|
||||||
tunfile = open(templatedir + "/tunable.html", "r")
|
|
||||||
tundata = tunfile.read()
|
|
||||||
tunfile.close()
|
|
||||||
boolfile = open(templatedir + "/boolean.html", "r")
|
|
||||||
booldata = boolfile.read()
|
|
||||||
boolfile.close()
|
|
||||||
menufile = open(templatedir + "/menu.html", "r")
|
|
||||||
menudata = menufile.read()
|
|
||||||
menufile.close()
|
|
||||||
indexfile = open(templatedir + "/module_list.html","r")
|
|
||||||
indexdata = indexfile.read()
|
|
||||||
indexfile.close()
|
|
||||||
modulefile = open(templatedir + "/module.html","r")
|
|
||||||
moduledata = modulefile.read()
|
|
||||||
modulefile.close()
|
|
||||||
intlistfile = open(templatedir + "/int_list.html", "r")
|
|
||||||
intlistdata = intlistfile.read()
|
|
||||||
intlistfile.close()
|
|
||||||
templistfile = open(templatedir + "/temp_list.html", "r")
|
|
||||||
templistdata = templistfile.read()
|
|
||||||
templistfile.close()
|
|
||||||
tunlistfile = open(templatedir + "/tun_list.html", "r")
|
|
||||||
tunlistdata = tunlistfile.read()
|
|
||||||
tunlistfile.close()
|
|
||||||
boollistfile = open(templatedir + "/bool_list.html", "r")
|
|
||||||
boollistdata = boollistfile.read()
|
|
||||||
boollistfile.close()
|
|
||||||
gboollistfile = open(templatedir + "/global_bool_list.html", "r")
|
|
||||||
gboollistdata = gboollistfile.read()
|
|
||||||
gboollistfile.close()
|
|
||||||
gtunlistfile = open(templatedir + "/global_tun_list.html", "r")
|
|
||||||
gtunlistdata = gtunlistfile.read()
|
|
||||||
gtunlistfile.close()
|
|
||||||
except:
|
|
||||||
error("Could not open templates")
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.chdir(working_dir)
|
|
||||||
except:
|
|
||||||
error("Could not chdir to target directory")
|
|
||||||
|
|
||||||
|
|
||||||
#arg, i have to go through this dom tree ahead of time to build up the menus
|
|
||||||
module_list = {}
|
|
||||||
for node in doc.getElementsByTagName("module"):
|
|
||||||
mod_name = mod_layer = interface_buf = ''
|
|
||||||
|
|
||||||
mod_name = node.getAttribute("name")
|
|
||||||
mod_layer = node.parentNode.getAttribute("name")
|
|
||||||
|
|
||||||
for desc in node.getElementsByTagName("summary"):
|
|
||||||
if desc.parentNode == node and desc:
|
|
||||||
mod_summary = format_html_desc(desc)
|
|
||||||
if not module_list.has_key(mod_layer):
|
|
||||||
module_list[mod_layer] = {}
|
|
||||||
|
|
||||||
module_list[mod_layer][mod_name] = mod_summary
|
|
||||||
|
|
||||||
#generate index pages
|
|
||||||
main_content_buf = ''
|
|
||||||
for mod_layer,modules in module_list.iteritems():
|
|
||||||
menu = gen_doc_menu(mod_layer, module_list)
|
|
||||||
|
|
||||||
layer_summary = None
|
|
||||||
for desc in doc.getElementsByTagName("summary"):
|
|
||||||
if desc.parentNode.getAttribute("name") == mod_layer:
|
|
||||||
layer_summary = format_html_desc(desc)
|
|
||||||
|
|
||||||
menu_args = { "menulist" : menu,
|
|
||||||
"mod_layer" : mod_layer,
|
|
||||||
"layer_summary" : layer_summary }
|
|
||||||
menu_tpl = pyplate.Template(menudata)
|
|
||||||
menu_buf = menu_tpl.execute_string(menu_args)
|
|
||||||
|
|
||||||
content_tpl = pyplate.Template(indexdata)
|
|
||||||
content_buf = content_tpl.execute_string(menu_args)
|
|
||||||
|
|
||||||
main_content_buf += content_buf
|
|
||||||
|
|
||||||
body_args = { "menu" : menu_buf,
|
|
||||||
"content" : content_buf }
|
|
||||||
|
|
||||||
index_file = mod_layer + ".html"
|
|
||||||
index_fh = open(index_file, "w")
|
|
||||||
body_tpl = pyplate.Template(bodydata)
|
|
||||||
body_tpl.execute(index_fh, body_args)
|
|
||||||
index_fh.close()
|
|
||||||
|
|
||||||
menu = gen_doc_menu(None, module_list)
|
|
||||||
menu_args = { "menulist" : menu,
|
|
||||||
"mod_layer" : None }
|
|
||||||
menu_tpl = pyplate.Template(menudata)
|
|
||||||
menu_buf = menu_tpl.execute_string(menu_args)
|
|
||||||
|
|
||||||
body_args = { "menu" : menu_buf,
|
|
||||||
"content" : main_content_buf }
|
|
||||||
|
|
||||||
index_file = "index.html"
|
|
||||||
index_fh = open(index_file, "w")
|
|
||||||
body_tpl = pyplate.Template(bodydata)
|
|
||||||
body_tpl.execute(index_fh, body_args)
|
|
||||||
index_fh.close()
|
|
||||||
#now generate the individual module pages
|
|
||||||
|
|
||||||
all_interfaces = []
|
|
||||||
all_templates = []
|
|
||||||
all_tunables = []
|
|
||||||
all_booleans = []
|
|
||||||
for node in doc.getElementsByTagName("module"):
|
|
||||||
mod_name = mod_layer = mod_desc = interface_buf = ''
|
|
||||||
|
|
||||||
mod_name = node.getAttribute("name")
|
|
||||||
mod_layer = node.parentNode.getAttribute("name")
|
|
||||||
|
|
||||||
mod_req = None
|
|
||||||
for req in node.getElementsByTagName("required"):
|
|
||||||
if req.getAttribute("val") == "true":
|
|
||||||
mod_req = True
|
|
||||||
|
|
||||||
for desc in node.getElementsByTagName("summary"):
|
|
||||||
if desc.parentNode == node:
|
|
||||||
mod_summary = format_html_desc(desc)
|
|
||||||
for desc in node.getElementsByTagName("desc"):
|
|
||||||
if desc.parentNode == node:
|
|
||||||
mod_desc = format_html_desc(desc)
|
|
||||||
|
|
||||||
interfaces = []
|
|
||||||
for interface in node.getElementsByTagName("interface"):
|
|
||||||
interface_parameters = []
|
|
||||||
interface_desc = interface_summary = None
|
|
||||||
interface_name = interface.getAttribute("name")
|
|
||||||
interface_line = interface.getAttribute("lineno")
|
|
||||||
for desc in interface.childNodes:
|
|
||||||
if desc.nodeName == "desc":
|
|
||||||
interface_desc = format_html_desc(desc)
|
|
||||||
elif desc.nodeName == "summary":
|
|
||||||
interface_summary = format_html_desc(desc)
|
|
||||||
|
|
||||||
for args in interface.getElementsByTagName("param"):
|
|
||||||
for desc in args.getElementsByTagName("summary"):
|
|
||||||
paramdesc = format_html_desc(desc)
|
|
||||||
paramname = args.getAttribute("name")
|
|
||||||
if args.getAttribute("optional") == "true":
|
|
||||||
paramopt = "Yes"
|
|
||||||
else:
|
|
||||||
paramopt = "No"
|
|
||||||
if args.getAttribute("unused") == "true":
|
|
||||||
paramunused = "Yes"
|
|
||||||
else:
|
|
||||||
paramunused = "No"
|
|
||||||
parameter = { "name" : paramname,
|
|
||||||
"desc" : paramdesc,
|
|
||||||
"optional" : paramopt,
|
|
||||||
"unused" : paramunused }
|
|
||||||
interface_parameters.append(parameter)
|
|
||||||
interfaces.append( { "interface_name" : interface_name,
|
|
||||||
"interface_summary" : interface_summary,
|
|
||||||
"interface_desc" : interface_desc,
|
|
||||||
"interface_parameters" : interface_parameters })
|
|
||||||
#all_interfaces is for the main interface index with all interfaces
|
|
||||||
all_interfaces.append( { "interface_name" : interface_name,
|
|
||||||
"interface_summary" : interface_summary,
|
|
||||||
"interface_desc" : interface_desc,
|
|
||||||
"interface_parameters" : interface_parameters,
|
|
||||||
"mod_name": mod_name,
|
|
||||||
"mod_layer" : mod_layer })
|
|
||||||
interfaces.sort(int_cmp)
|
|
||||||
interface_tpl = pyplate.Template(intdata)
|
|
||||||
interface_buf = interface_tpl.execute_string({"interfaces" : interfaces})
|
|
||||||
|
|
||||||
|
|
||||||
# now generate individual template pages
|
|
||||||
templates = []
|
|
||||||
for template in node.getElementsByTagName("template"):
|
|
||||||
template_parameters = []
|
|
||||||
template_desc = template_summary = None
|
|
||||||
template_name = template.getAttribute("name")
|
|
||||||
template_line = template.getAttribute("lineno")
|
|
||||||
for desc in template.childNodes:
|
|
||||||
if desc.nodeName == "desc":
|
|
||||||
template_desc = format_html_desc(desc)
|
|
||||||
elif desc.nodeName == "summary":
|
|
||||||
template_summary = format_html_desc(desc)
|
|
||||||
|
|
||||||
for args in template.getElementsByTagName("param"):
|
|
||||||
for desc in args.getElementsByTagName("summary"):
|
|
||||||
paramdesc = format_html_desc(desc)
|
|
||||||
paramname = args.getAttribute("name")
|
|
||||||
if args.getAttribute("optional") == "true":
|
|
||||||
paramopt = "Yes"
|
|
||||||
else:
|
|
||||||
paramopt = "No"
|
|
||||||
if args.getAttribute("unused") == "true":
|
|
||||||
paramunused = "Yes"
|
|
||||||
else:
|
|
||||||
paramunused = "No"
|
|
||||||
parameter = { "name" : paramname,
|
|
||||||
"desc" : paramdesc,
|
|
||||||
"optional" : paramopt,
|
|
||||||
"unused": paramunused }
|
|
||||||
template_parameters.append(parameter)
|
|
||||||
templates.append( { "template_name" : template_name,
|
|
||||||
"template_summary" : template_summary,
|
|
||||||
"template_desc" : template_desc,
|
|
||||||
"template_parameters" : template_parameters })
|
|
||||||
#all_templates is for the main interface index with all templates
|
|
||||||
all_templates.append( { "template_name" : template_name,
|
|
||||||
"template_summary" : template_summary,
|
|
||||||
"template_desc" : template_desc,
|
|
||||||
"template_parameters" : template_parameters,
|
|
||||||
"mod_name": mod_name,
|
|
||||||
"mod_layer" : mod_layer })
|
|
||||||
|
|
||||||
templates.sort(temp_cmp)
|
|
||||||
template_tpl = pyplate.Template(templatedata)
|
|
||||||
template_buf = template_tpl.execute_string({"templates" : templates})
|
|
||||||
|
|
||||||
#generate 'boolean' pages
|
|
||||||
booleans = []
|
|
||||||
for boolean in node.getElementsByTagName("bool"):
|
|
||||||
boolean_parameters = []
|
|
||||||
boolean_desc = None
|
|
||||||
boolean_name = boolean.getAttribute("name")
|
|
||||||
boolean_dftval = boolean.getAttribute("dftval")
|
|
||||||
for desc in boolean.childNodes:
|
|
||||||
if desc.nodeName == "desc":
|
|
||||||
boolean_desc = format_html_desc(desc)
|
|
||||||
|
|
||||||
booleans.append({ "bool_name" : boolean_name,
|
|
||||||
"desc" : boolean_desc,
|
|
||||||
"def_val" : boolean_dftval })
|
|
||||||
#all_booleans is for the main boolean index with all booleans
|
|
||||||
all_booleans.append({ "bool_name" : boolean_name,
|
|
||||||
"desc" : boolean_desc,
|
|
||||||
"def_val" : boolean_dftval,
|
|
||||||
"mod_name": mod_name,
|
|
||||||
"mod_layer" : mod_layer })
|
|
||||||
booleans.sort(bool_cmp)
|
|
||||||
boolean_tpl = pyplate.Template(booldata)
|
|
||||||
boolean_buf = boolean_tpl.execute_string({"booleans" : booleans})
|
|
||||||
|
|
||||||
#generate 'tunable' pages
|
|
||||||
tunables = []
|
|
||||||
for tunable in node.getElementsByTagName("tunable"):
|
|
||||||
tunable_parameters = []
|
|
||||||
tunable_desc = None
|
|
||||||
tunable_name = tunable.getAttribute("name")
|
|
||||||
tunable_dftval = tunable.getAttribute("dftval")
|
|
||||||
for desc in tunable.childNodes:
|
|
||||||
if desc.nodeName == "desc":
|
|
||||||
tunable_desc = format_html_desc(desc)
|
|
||||||
|
|
||||||
tunables.append({ "tun_name" : tunable_name,
|
|
||||||
"desc" : tunable_desc,
|
|
||||||
"def_val" : tunable_dftval })
|
|
||||||
#all_tunables is for the main tunable index with all tunables
|
|
||||||
all_tunables.append({ "tun_name" : tunable_name,
|
|
||||||
"desc" : tunable_desc,
|
|
||||||
"def_val" : tunable_dftval,
|
|
||||||
"mod_name": mod_name,
|
|
||||||
"mod_layer" : mod_layer })
|
|
||||||
tunables.sort(tun_cmp)
|
|
||||||
tunable_tpl = pyplate.Template(tundata)
|
|
||||||
tunable_buf = tunable_tpl.execute_string({"tunables" : tunables})
|
|
||||||
|
|
||||||
|
|
||||||
menu = gen_doc_menu(mod_layer, module_list)
|
|
||||||
|
|
||||||
menu_tpl = pyplate.Template(menudata)
|
|
||||||
menu_buf = menu_tpl.execute_string({ "menulist" : menu })
|
|
||||||
|
|
||||||
|
|
||||||
# pyplate's execute_string gives us a line of whitespace in
|
|
||||||
# template_buf or interface_buf if there are no interfaces or
|
|
||||||
# templates for this module. This is problematic because the
|
|
||||||
# HTML templates use a conditional if on interface_buf or
|
|
||||||
# template_buf being 'None' to decide if the "Template:" or
|
|
||||||
# "Interface:" headers need to be printed in the module pages.
|
|
||||||
# This detects if either of these are just whitespace, and sets
|
|
||||||
# their values to 'None' so that when applying it to the
|
|
||||||
# templates, they are properly recognized as not existing.
|
|
||||||
if not interface_buf.strip():
|
|
||||||
interface_buf = None
|
|
||||||
if not template_buf.strip():
|
|
||||||
template_buf = None
|
|
||||||
if not tunable_buf.strip():
|
|
||||||
tunable_buf = None
|
|
||||||
if not boolean_buf.strip():
|
|
||||||
boolean_buf = None
|
|
||||||
|
|
||||||
module_args = { "mod_layer" : mod_layer,
|
|
||||||
"mod_name" : mod_name,
|
|
||||||
"mod_summary" : mod_summary,
|
|
||||||
"mod_desc" : mod_desc,
|
|
||||||
"mod_req" : mod_req,
|
|
||||||
"interfaces" : interface_buf,
|
|
||||||
"templates" : template_buf,
|
|
||||||
"tunables" : tunable_buf,
|
|
||||||
"booleans" : boolean_buf }
|
|
||||||
|
|
||||||
module_tpl = pyplate.Template(moduledata)
|
|
||||||
module_buf = module_tpl.execute_string(module_args)
|
|
||||||
|
|
||||||
body_args = { "menu" : menu_buf,
|
|
||||||
"content" : module_buf }
|
|
||||||
|
|
||||||
module_file = mod_layer + "_" + mod_name + ".html"
|
|
||||||
module_fh = open(module_file, "w")
|
|
||||||
body_tpl = pyplate.Template(bodydata)
|
|
||||||
body_tpl.execute(module_fh, body_args)
|
|
||||||
module_fh.close()
|
|
||||||
|
|
||||||
|
|
||||||
menu = gen_doc_menu(None, module_list)
|
|
||||||
menu_args = { "menulist" : menu,
|
|
||||||
"mod_layer" : None }
|
|
||||||
menu_tpl = pyplate.Template(menudata)
|
|
||||||
menu_buf = menu_tpl.execute_string(menu_args)
|
|
||||||
|
|
||||||
#build the interface index
|
|
||||||
all_interfaces.sort(int_cmp)
|
|
||||||
interface_tpl = pyplate.Template(intlistdata)
|
|
||||||
interface_buf = interface_tpl.execute_string({"interfaces" : all_interfaces})
|
|
||||||
int_file = "interfaces.html"
|
|
||||||
int_fh = open(int_file, "w")
|
|
||||||
body_tpl = pyplate.Template(bodydata)
|
|
||||||
|
|
||||||
body_args = { "menu" : menu_buf,
|
|
||||||
"content" : interface_buf }
|
|
||||||
|
|
||||||
body_tpl.execute(int_fh, body_args)
|
|
||||||
int_fh.close()
|
|
||||||
|
|
||||||
|
|
||||||
#build the template index
|
|
||||||
all_templates.sort(temp_cmp)
|
|
||||||
template_tpl = pyplate.Template(templistdata)
|
|
||||||
template_buf = template_tpl.execute_string({"templates" : all_templates})
|
|
||||||
temp_file = "templates.html"
|
|
||||||
temp_fh = open(temp_file, "w")
|
|
||||||
body_tpl = pyplate.Template(bodydata)
|
|
||||||
|
|
||||||
body_args = { "menu" : menu_buf,
|
|
||||||
"content" : template_buf }
|
|
||||||
|
|
||||||
body_tpl.execute(temp_fh, body_args)
|
|
||||||
temp_fh.close()
|
|
||||||
|
|
||||||
|
|
||||||
#build the global tunable index
|
|
||||||
global_tun = []
|
|
||||||
for tunable in doc.getElementsByTagName("tunable"):
|
|
||||||
if tunable.parentNode.nodeName == "policy":
|
|
||||||
tunable_name = tunable.getAttribute("name")
|
|
||||||
default_value = tunable.getAttribute("dftval")
|
|
||||||
for desc in tunable.getElementsByTagName("desc"):
|
|
||||||
description = format_html_desc(desc)
|
|
||||||
global_tun.append( { "tun_name" : tunable_name,
|
|
||||||
"def_val" : default_value,
|
|
||||||
"desc" : description } )
|
|
||||||
global_tun.sort(tun_cmp)
|
|
||||||
global_tun_tpl = pyplate.Template(gtunlistdata)
|
|
||||||
global_tun_buf = global_tun_tpl.execute_string({"tunables" : global_tun})
|
|
||||||
global_tun_file = "global_tunables.html"
|
|
||||||
global_tun_fh = open(global_tun_file, "w")
|
|
||||||
body_tpl = pyplate.Template(bodydata)
|
|
||||||
|
|
||||||
body_args = { "menu" : menu_buf,
|
|
||||||
"content" : global_tun_buf }
|
|
||||||
|
|
||||||
body_tpl.execute(global_tun_fh, body_args)
|
|
||||||
global_tun_fh.close()
|
|
||||||
|
|
||||||
#build the tunable index
|
|
||||||
all_tunables = all_tunables + global_tun
|
|
||||||
all_tunables.sort(tun_cmp)
|
|
||||||
tunable_tpl = pyplate.Template(tunlistdata)
|
|
||||||
tunable_buf = tunable_tpl.execute_string({"tunables" : all_tunables})
|
|
||||||
temp_file = "tunables.html"
|
|
||||||
temp_fh = open(temp_file, "w")
|
|
||||||
body_tpl = pyplate.Template(bodydata)
|
|
||||||
|
|
||||||
body_args = { "menu" : menu_buf,
|
|
||||||
"content" : tunable_buf }
|
|
||||||
|
|
||||||
body_tpl.execute(temp_fh, body_args)
|
|
||||||
temp_fh.close()
|
|
||||||
|
|
||||||
#build the global boolean index
|
|
||||||
global_bool = []
|
|
||||||
for boolean in doc.getElementsByTagName("bool"):
|
|
||||||
if boolean.parentNode.nodeName == "policy":
|
|
||||||
bool_name = boolean.getAttribute("name")
|
|
||||||
default_value = boolean.getAttribute("dftval")
|
|
||||||
for desc in boolean.getElementsByTagName("desc"):
|
|
||||||
description = format_html_desc(desc)
|
|
||||||
global_bool.append( { "bool_name" : bool_name,
|
|
||||||
"def_val" : default_value,
|
|
||||||
"desc" : description } )
|
|
||||||
global_bool.sort(bool_cmp)
|
|
||||||
global_bool_tpl = pyplate.Template(gboollistdata)
|
|
||||||
global_bool_buf = global_bool_tpl.execute_string({"booleans" : global_bool})
|
|
||||||
global_bool_file = "global_booleans.html"
|
|
||||||
global_bool_fh = open(global_bool_file, "w")
|
|
||||||
body_tpl = pyplate.Template(bodydata)
|
|
||||||
|
|
||||||
body_args = { "menu" : menu_buf,
|
|
||||||
"content" : global_bool_buf }
|
|
||||||
|
|
||||||
body_tpl.execute(global_bool_fh, body_args)
|
|
||||||
global_bool_fh.close()
|
|
||||||
|
|
||||||
#build the boolean index
|
|
||||||
all_booleans = all_booleans + global_bool
|
|
||||||
all_booleans.sort(bool_cmp)
|
|
||||||
boolean_tpl = pyplate.Template(boollistdata)
|
|
||||||
boolean_buf = boolean_tpl.execute_string({"booleans" : all_booleans})
|
|
||||||
temp_file = "booleans.html"
|
|
||||||
temp_fh = open(temp_file, "w")
|
|
||||||
body_tpl = pyplate.Template(bodydata)
|
|
||||||
|
|
||||||
body_args = { "menu" : menu_buf,
|
|
||||||
"content" : boolean_buf }
|
|
||||||
|
|
||||||
body_tpl.execute(temp_fh, body_args)
|
|
||||||
temp_fh.close()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def error(error):
|
|
||||||
"""
|
|
||||||
Print an error message and exit.
|
|
||||||
"""
|
|
||||||
|
|
||||||
sys.stderr.write("%s exiting for: " % sys.argv[0])
|
|
||||||
sys.stderr.write("%s\n" % error)
|
|
||||||
sys.stderr.flush()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def warning(warn):
|
|
||||||
"""
|
|
||||||
Print a warning message.
|
|
||||||
"""
|
|
||||||
|
|
||||||
sys.stderr.write("%s warning: " % sys.argv[0])
|
|
||||||
sys.stderr.write("%s\n" % warn)
|
|
||||||
|
|
||||||
def usage():
|
|
||||||
"""
|
|
||||||
Describes the proper usage of this tool.
|
|
||||||
"""
|
|
||||||
|
|
||||||
sys.stdout.write("%s [-tmdT] -x <xmlfile>\n\n" % sys.argv[0])
|
|
||||||
sys.stdout.write("Options:\n")
|
|
||||||
sys.stdout.write("-b --booleans <file> -- write boolean config to <file>\n")
|
|
||||||
sys.stdout.write("-m --modules <file> -- write module config to <file>\n")
|
|
||||||
sys.stdout.write("-d --docs <dir> -- write interface documentation to <dir>\n")
|
|
||||||
sys.stdout.write("-x --xml <file> -- filename to read xml data from\n")
|
|
||||||
sys.stdout.write("-T --templates <dir> -- template directory for documents\n")
|
|
||||||
|
|
||||||
|
|
||||||
# MAIN PROGRAM
|
|
||||||
try:
|
|
||||||
opts, args = getopt.getopt(sys.argv[1:], "b:m:d:x:T:", ["booleans","modules","docs","xml", "templates"])
|
|
||||||
except getopt.GetoptError:
|
|
||||||
usage()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
booleans = modules = docsdir = None
|
|
||||||
templatedir = "templates/"
|
|
||||||
xmlfile = "policy.xml"
|
|
||||||
|
|
||||||
for opt, val in opts:
|
|
||||||
if opt in ("-b", "--booleans"):
|
|
||||||
booleans = val
|
|
||||||
if opt in ("-m", "--modules"):
|
|
||||||
modules = val
|
|
||||||
if opt in ("-d", "--docs"):
|
|
||||||
docsdir = val
|
|
||||||
if opt in ("-x", "--xml"):
|
|
||||||
xmlfile = val
|
|
||||||
if opt in ("-T", "--templates"):
|
|
||||||
templatedir = val
|
|
||||||
|
|
||||||
doc = read_policy_xml(xmlfile)
|
|
||||||
|
|
||||||
if booleans:
|
|
||||||
namevalue_list = []
|
|
||||||
if os.path.exists(booleans):
|
|
||||||
try:
|
|
||||||
conf = open(booleans, 'r')
|
|
||||||
except:
|
|
||||||
error("Could not open booleans file for reading")
|
|
||||||
|
|
||||||
namevalue_list = get_conf(conf)
|
|
||||||
|
|
||||||
conf.close()
|
|
||||||
|
|
||||||
try:
|
|
||||||
conf = open(booleans, 'w')
|
|
||||||
except:
|
|
||||||
error("Could not open booleans file for writing")
|
|
||||||
|
|
||||||
gen_booleans_conf(doc, conf, namevalue_list)
|
|
||||||
conf.close()
|
|
||||||
|
|
||||||
|
|
||||||
if modules:
|
|
||||||
namevalue_list = []
|
|
||||||
if os.path.exists(modules):
|
|
||||||
try:
|
|
||||||
conf = open(modules, 'r')
|
|
||||||
except:
|
|
||||||
error("Could not open modules file for reading")
|
|
||||||
namevalue_list = get_conf(conf)
|
|
||||||
conf.close()
|
|
||||||
|
|
||||||
try:
|
|
||||||
conf = open(modules, 'w')
|
|
||||||
except:
|
|
||||||
error("Could not open modules file for writing")
|
|
||||||
gen_module_conf(doc, conf, namevalue_list)
|
|
||||||
conf.close()
|
|
||||||
|
|
||||||
if docsdir:
|
|
||||||
gen_docs(doc, docsdir, templatedir)
|
|
@ -1,391 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
# Author(s): Donald Miner <dminer@tresys.com>
|
|
||||||
# Dave Sugar <dsugar@tresys.com>
|
|
||||||
# Brian Williams <bwilliams@tresys.com>
|
|
||||||
# Caleb Case <ccase@tresys.com>
|
|
||||||
#
|
|
||||||
# Copyright (C) 2005 - 2006 Tresys Technology, LLC
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, version 2.
|
|
||||||
|
|
||||||
"""
|
|
||||||
This script generates XML documentation information for layers specified
|
|
||||||
by the user.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import glob
|
|
||||||
import re
|
|
||||||
import getopt
|
|
||||||
|
|
||||||
# GLOBALS
|
|
||||||
|
|
||||||
# Default values of command line arguments:
|
|
||||||
warn = False
|
|
||||||
meta = "metadata"
|
|
||||||
third_party = "third-party"
|
|
||||||
layers = {}
|
|
||||||
tunable_files = []
|
|
||||||
bool_files = []
|
|
||||||
xml_tunable_files = []
|
|
||||||
xml_bool_files = []
|
|
||||||
output_dir = ""
|
|
||||||
|
|
||||||
# Pre compiled regular expressions:
|
|
||||||
|
|
||||||
# Matches either an interface or a template declaration. Will give the tuple:
|
|
||||||
# ("interface" or "template", name)
|
|
||||||
# Some examples:
|
|
||||||
# "interface(`kernel_read_system_state',`"
|
|
||||||
# -> ("interface", "kernel_read_system_state")
|
|
||||||
# "template(`base_user_template',`"
|
|
||||||
# -> ("template", "base_user_template")
|
|
||||||
INTERFACE = re.compile("^\s*(interface|template)\(`(\w*)'")
|
|
||||||
|
|
||||||
# Matches either a gen_bool or a gen_tunable statement. Will give the tuple:
|
|
||||||
# ("tunable" or "bool", name, "true" or "false")
|
|
||||||
# Some examples:
|
|
||||||
# "gen_bool(secure_mode, false)"
|
|
||||||
# -> ("bool", "secure_mode", "false")
|
|
||||||
# "gen_tunable(allow_kerberos, false)"
|
|
||||||
# -> ("tunable", "allow_kerberos", "false")
|
|
||||||
BOOLEAN = re.compile("^\s*gen_(tunable|bool)\(\s*(\w*)\s*,\s*(true|false)\s*\)")
|
|
||||||
|
|
||||||
# Matches a XML comment in the policy, which is defined as any line starting
|
|
||||||
# with two # and at least one character of white space. Will give the single
|
|
||||||
# valued tuple:
|
|
||||||
# ("comment")
|
|
||||||
# Some Examples:
|
|
||||||
# "## <summary>"
|
|
||||||
# -> ("<summary>")
|
|
||||||
# "## The domain allowed access. "
|
|
||||||
# -> ("The domain allowed access.")
|
|
||||||
XML_COMMENT = re.compile("^##\s+(.*?)\s*$")
|
|
||||||
|
|
||||||
|
|
||||||
# FUNCTIONS
|
|
||||||
def getModuleXML(file_name):
|
|
||||||
'''
|
|
||||||
Returns the XML data for a module in a list, one line per list item.
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Gather information.
|
|
||||||
module_dir = os.path.dirname(file_name)
|
|
||||||
module_name = os.path.basename(file_name)
|
|
||||||
module_te = "%s/%s.te" % (module_dir, module_name)
|
|
||||||
module_if = "%s/%s.if" % (module_dir, module_name)
|
|
||||||
|
|
||||||
# Try to open the file, if it cant, just ignore it.
|
|
||||||
try:
|
|
||||||
module_file = open(module_if, "r")
|
|
||||||
module_code = module_file.readlines()
|
|
||||||
module_file.close()
|
|
||||||
except:
|
|
||||||
warning("cannot open file %s for read, skipping" % file_name)
|
|
||||||
return []
|
|
||||||
|
|
||||||
module_buf = []
|
|
||||||
|
|
||||||
# Infer the module name, which is the base of the file name.
|
|
||||||
module_buf.append("<module name=\"%s\" filename=\"%s\">\n"
|
|
||||||
% (os.path.splitext(os.path.split(file_name)[-1])[0], module_if))
|
|
||||||
|
|
||||||
temp_buf = []
|
|
||||||
interface = None
|
|
||||||
|
|
||||||
# finding_header is a flag to denote whether we are still looking
|
|
||||||
# for the XML documentation at the head of the file.
|
|
||||||
finding_header = True
|
|
||||||
|
|
||||||
# Get rid of whitespace at top of file
|
|
||||||
while(module_code and module_code[0].isspace()):
|
|
||||||
module_code = module_code[1:]
|
|
||||||
|
|
||||||
# Go line by line and figure out what to do with it.
|
|
||||||
line_num = 0
|
|
||||||
for line in module_code:
|
|
||||||
line_num += 1
|
|
||||||
if finding_header:
|
|
||||||
# If there is a XML comment, add it to the temp buffer.
|
|
||||||
comment = XML_COMMENT.match(line)
|
|
||||||
if comment:
|
|
||||||
temp_buf.append(comment.group(1) + "\n")
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Once a line that is not an XML comment is reached,
|
|
||||||
# either put the XML out to module buffer as the
|
|
||||||
# module's documentation, or attribute it to an
|
|
||||||
# interface/template.
|
|
||||||
elif temp_buf:
|
|
||||||
finding_header = False
|
|
||||||
interface = INTERFACE.match(line)
|
|
||||||
if not interface:
|
|
||||||
module_buf += temp_buf
|
|
||||||
temp_buf = []
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Skip over empty lines
|
|
||||||
if line.isspace():
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Grab a comment and add it to the temprorary buffer, if it
|
|
||||||
# is there.
|
|
||||||
comment = XML_COMMENT.match(line)
|
|
||||||
if comment:
|
|
||||||
temp_buf.append(comment.group(1) + "\n")
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Grab the interface information. This is only not true when
|
|
||||||
# the interface is at the top of the file and there is no
|
|
||||||
# documentation for the module.
|
|
||||||
if not interface:
|
|
||||||
interface = INTERFACE.match(line)
|
|
||||||
if interface:
|
|
||||||
# Add the opening tag for the interface/template
|
|
||||||
groups = interface.groups()
|
|
||||||
module_buf.append("<%s name=\"%s\" lineno=\"%s\">\n" % (groups[0], groups[1], line_num))
|
|
||||||
|
|
||||||
# Add all the comments attributed to this interface to
|
|
||||||
# the module buffer.
|
|
||||||
if temp_buf:
|
|
||||||
module_buf += temp_buf
|
|
||||||
temp_buf = []
|
|
||||||
|
|
||||||
# Add default summaries and parameters so that the
|
|
||||||
# DTD is happy.
|
|
||||||
else:
|
|
||||||
warning ("unable to find XML for %s %s()" % (groups[0], groups[1]))
|
|
||||||
module_buf.append("<summary>\n")
|
|
||||||
module_buf.append("Summary is missing!\n")
|
|
||||||
module_buf.append("</summary>\n")
|
|
||||||
module_buf.append("<param name=\"?\">\n")
|
|
||||||
module_buf.append("<summary>\n")
|
|
||||||
module_buf.append("Parameter descriptions are missing!\n")
|
|
||||||
module_buf.append("</summary>\n")
|
|
||||||
module_buf.append("</param>\n")
|
|
||||||
|
|
||||||
# Close the interface/template tag.
|
|
||||||
module_buf.append("</%s>\n" % interface.group(1))
|
|
||||||
|
|
||||||
interface = None
|
|
||||||
continue
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# If the file just had a header, add the comments to the module buffer.
|
|
||||||
if finding_header:
|
|
||||||
module_buf += temp_buf
|
|
||||||
# Otherwise there are some lingering XML comments at the bottom, warn
|
|
||||||
# the user.
|
|
||||||
elif temp_buf:
|
|
||||||
warning("orphan XML comments at bottom of file %s" % file_name)
|
|
||||||
|
|
||||||
# Process the TE file if it exists.
|
|
||||||
module_buf = module_buf + getTunableXML(module_te, "both")
|
|
||||||
|
|
||||||
module_buf.append("</module>\n")
|
|
||||||
|
|
||||||
return module_buf
|
|
||||||
|
|
||||||
def getTunableXML(file_name, kind):
|
|
||||||
'''
|
|
||||||
Return all the XML for the tunables/bools in the file specified.
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Try to open the file, if it cant, just ignore it.
|
|
||||||
try:
|
|
||||||
tunable_file = open(file_name, "r")
|
|
||||||
tunable_code = tunable_file.readlines()
|
|
||||||
tunable_file.close()
|
|
||||||
except:
|
|
||||||
warning("cannot open file %s for read, skipping" % file_name)
|
|
||||||
return []
|
|
||||||
|
|
||||||
tunable_buf = []
|
|
||||||
temp_buf = []
|
|
||||||
|
|
||||||
# Find tunables and booleans line by line and use the comments above
|
|
||||||
# them.
|
|
||||||
for line in tunable_code:
|
|
||||||
# If it is an XML comment, add it to the buffer and go on.
|
|
||||||
comment = XML_COMMENT.match(line)
|
|
||||||
if comment:
|
|
||||||
temp_buf.append(comment.group(1) + "\n")
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Get the boolean/tunable data.
|
|
||||||
boolean = BOOLEAN.match(line)
|
|
||||||
|
|
||||||
# If we reach a boolean/tunable declaration, attribute all XML
|
|
||||||
# in the temp buffer to it and add XML to the tunable buffer.
|
|
||||||
if boolean:
|
|
||||||
# If there is a gen_bool in a tunable file or a
|
|
||||||
# gen_tunable in a boolean file, error and exit.
|
|
||||||
# Skip if both kinds are valid.
|
|
||||||
if kind != "both":
|
|
||||||
if boolean.group(1) != kind:
|
|
||||||
error("%s in a %s file." % (boolean.group(1), kind))
|
|
||||||
|
|
||||||
tunable_buf.append("<%s name=\"%s\" dftval=\"%s\">\n" % boolean.groups())
|
|
||||||
tunable_buf += temp_buf
|
|
||||||
temp_buf = []
|
|
||||||
tunable_buf.append("</%s>\n" % boolean.group(1))
|
|
||||||
|
|
||||||
# If there are XML comments at the end of the file, they arn't
|
|
||||||
# attributed to anything. These are ignored.
|
|
||||||
if len(temp_buf):
|
|
||||||
warning("orphan XML comments at bottom of file %s" % file_name)
|
|
||||||
|
|
||||||
|
|
||||||
# If the caller requested a the global_tunables and global_booleans to be
|
|
||||||
# output to a file output them now
|
|
||||||
if len(output_dir) > 0:
|
|
||||||
xmlfile = os.path.split(file_name)[1] + ".xml"
|
|
||||||
|
|
||||||
try:
|
|
||||||
xml_outfile = open(output_dir + "/" + xmlfile, "w")
|
|
||||||
for tunable_line in tunable_buf:
|
|
||||||
xml_outfile.write (tunable_line)
|
|
||||||
xml_outfile.close()
|
|
||||||
except:
|
|
||||||
warning ("cannot write to file %s, skipping creation" % xmlfile)
|
|
||||||
|
|
||||||
return tunable_buf
|
|
||||||
|
|
||||||
def getXMLFileContents (file_name):
|
|
||||||
'''
|
|
||||||
Return all the XML in the file specified.
|
|
||||||
'''
|
|
||||||
|
|
||||||
tunable_buf = []
|
|
||||||
# Try to open the xml file for this type of file
|
|
||||||
# append the contents to the buffer.
|
|
||||||
try:
|
|
||||||
tunable_xml = open(file_name, "r")
|
|
||||||
tunable_buf += tunable_xml.readlines()
|
|
||||||
tunable_xml.close()
|
|
||||||
except:
|
|
||||||
warning("cannot open file %s for read, assuming no data" % file_name)
|
|
||||||
|
|
||||||
return tunable_buf
|
|
||||||
|
|
||||||
def getPolicyXML():
|
|
||||||
'''
|
|
||||||
Return the compelete reference policy XML documentation through a list,
|
|
||||||
one line per item.
|
|
||||||
'''
|
|
||||||
|
|
||||||
policy_buf = []
|
|
||||||
policy_buf.append("<policy>\n")
|
|
||||||
|
|
||||||
# Add to the XML each layer specified by the user.
|
|
||||||
for layer in layers.keys ():
|
|
||||||
policy_buf += getLayerXML(layer, layers[layer])
|
|
||||||
|
|
||||||
# Add to the XML each tunable file specified by the user.
|
|
||||||
for tunable_file in tunable_files:
|
|
||||||
policy_buf += getTunableXML(tunable_file, "tunable")
|
|
||||||
|
|
||||||
# Add to the XML each XML tunable file specified by the user.
|
|
||||||
for tunable_file in xml_tunable_files:
|
|
||||||
policy_buf += getXMLFileContents (tunable_file)
|
|
||||||
|
|
||||||
# Add to the XML each bool file specified by the user.
|
|
||||||
for bool_file in bool_files:
|
|
||||||
policy_buf += getTunableXML(bool_file, "bool")
|
|
||||||
|
|
||||||
# Add to the XML each XML bool file specified by the user.
|
|
||||||
for bool_file in xml_bool_files:
|
|
||||||
policy_buf += getXMLFileContents (bool_file)
|
|
||||||
|
|
||||||
policy_buf.append("</policy>\n")
|
|
||||||
|
|
||||||
return policy_buf
|
|
||||||
|
|
||||||
def usage():
|
|
||||||
"""
|
|
||||||
Displays a message describing the proper usage of this script.
|
|
||||||
"""
|
|
||||||
|
|
||||||
sys.stdout.write("usage: %s [-w] [-mtb] <file>\n\n" % sys.argv[0])
|
|
||||||
sys.stdout.write("-w --warn\t\t\tshow warnings\n"+\
|
|
||||||
"-m --module <file>\t\tname of module to process\n"+\
|
|
||||||
"-t --tunable <file>\t\tname of global tunable file to process\n"+\
|
|
||||||
"-b --boolean <file>\t\tname of global boolean file to process\n\n")
|
|
||||||
|
|
||||||
sys.stdout.write("examples:\n")
|
|
||||||
sys.stdout.write("> %s -w -m policy/modules/apache\n" % sys.argv[0])
|
|
||||||
sys.stdout.write("> %s -t policy/global_tunables\n" % sys.argv[0])
|
|
||||||
|
|
||||||
def warning(description):
|
|
||||||
'''
|
|
||||||
Warns the user of a non-critical error.
|
|
||||||
'''
|
|
||||||
|
|
||||||
if warn:
|
|
||||||
sys.stderr.write("%s: " % sys.argv[0] )
|
|
||||||
sys.stderr.write("warning: " + description + "\n")
|
|
||||||
|
|
||||||
def error(description):
|
|
||||||
'''
|
|
||||||
Describes an error and exists the program.
|
|
||||||
'''
|
|
||||||
|
|
||||||
sys.stderr.write("%s: " % sys.argv[0] )
|
|
||||||
sys.stderr.write("error: " + description + "\n")
|
|
||||||
sys.stderr.flush()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# MAIN PROGRAM
|
|
||||||
|
|
||||||
# Defaults
|
|
||||||
warn = False
|
|
||||||
module = False
|
|
||||||
tunable = False
|
|
||||||
boolean = False
|
|
||||||
|
|
||||||
# Check that there are command line arguments.
|
|
||||||
if len(sys.argv) <= 1:
|
|
||||||
usage()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Parse command line args
|
|
||||||
try:
|
|
||||||
opts, args = getopt.getopt(sys.argv[1:], 'whm:t:b:', ['warn', 'help', 'module=', 'tunable=', 'boolean='])
|
|
||||||
except getopt.GetoptError:
|
|
||||||
usage()
|
|
||||||
sys.exit(2)
|
|
||||||
for o, a in opts:
|
|
||||||
if o in ('-w', '--warn'):
|
|
||||||
warn = True
|
|
||||||
elif o in ('-h', '--help'):
|
|
||||||
usage()
|
|
||||||
sys.exit(0)
|
|
||||||
elif o in ('-m', '--module'):
|
|
||||||
module = a
|
|
||||||
break
|
|
||||||
elif o in ('-t', '--tunable'):
|
|
||||||
tunable = a
|
|
||||||
break
|
|
||||||
elif o in ('-b', '--boolean'):
|
|
||||||
boolean = a
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
usage()
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
if module:
|
|
||||||
sys.stdout.writelines(getModuleXML(module))
|
|
||||||
elif tunable:
|
|
||||||
sys.stdout.writelines(getTunableXML(tunable, "tunable"))
|
|
||||||
elif boolean:
|
|
||||||
sys.stdout.writelines(getTunableXML(boolean, "bool"))
|
|
||||||
else:
|
|
||||||
usage()
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
@ -1,435 +0,0 @@
|
|||||||
%define distro redhat
|
|
||||||
%define direct_initrc y
|
|
||||||
%define monolithic n
|
|
||||||
%define polname1 targeted
|
|
||||||
%define type1 targeted-mcs
|
|
||||||
%define polname2 strict
|
|
||||||
%define type2 strict-mcs
|
|
||||||
Summary: SELinux policy configuration
|
|
||||||
Name: selinux-policy
|
|
||||||
Version: 20051019
|
|
||||||
Release: 1
|
|
||||||
License: GPL
|
|
||||||
Group: System Environment/Base
|
|
||||||
Source: refpolicy-%{version}.tar.bz2
|
|
||||||
Url: http://serefpolicy.sourceforge.net
|
|
||||||
BuildRoot: %{_tmppath}/refpolicy-buildroot
|
|
||||||
BuildArch: noarch
|
|
||||||
# FIXME Need to ensure these have correct versions
|
|
||||||
BuildRequires: checkpolicy m4 policycoreutils python make gcc
|
|
||||||
PreReq: kernel >= 2.6.4-1.300 policycoreutils >= %{POLICYCOREUTILSVER}
|
|
||||||
Obsoletes: policy
|
|
||||||
|
|
||||||
%description
|
|
||||||
SELinux Reference Policy - modular.
|
|
||||||
|
|
||||||
%prep
|
|
||||||
%setup -q
|
|
||||||
make conf
|
|
||||||
|
|
||||||
%build
|
|
||||||
|
|
||||||
%install
|
|
||||||
%{__rm} -fR $RPM_BUILD_ROOT
|
|
||||||
make NAME=%{polname1} TYPE=%{type1} DISTRO=%{distro} DIRECT_INITRC=%{direct_initrc} MONOLITHIC=%{monolithic} base.pp
|
|
||||||
make NAME=%{polname1} TYPE=%{type1} DISTRO=%{distro} DIRECT_INITRC=%{direct_initrc} MONOLITHIC=%{monolithic} modules
|
|
||||||
%{__mkdir} -p $RPM_BUILD_ROOT/%{_usr}/share/selinux/%{polname1}/%{type1}
|
|
||||||
%{__cp} *.pp $RPM_BUILD_ROOT/%{_usr}/share/selinux/%{polname1}/%{type1}
|
|
||||||
%{__mkdir} -p $RPM_BUILD_ROOT/%{_sysconfdir}/selinux/%{polname1}/policy
|
|
||||||
%{__mkdir} -p $RPM_BUILD_ROOT/%{_sysconfdir}/selinux/%{polname1}/contexts/files
|
|
||||||
make NAME=%{polname1} TYPE=%{type1} DISTRO=%{distro} DIRECT_INITRC=%{direct_initrc} MONOLITHIC=y DESTDIR=$RPM_BUILD_ROOT install-appconfig
|
|
||||||
make NAME=%{polname1} TYPE=%{type1} DISTRO=%{distro} DIRECT_INITRC=%{direct_initrc} MONOLITHIC=%{monolithic} DESTDIR=$RPM_BUILD_ROOT $RPM_BUILD_ROOT%{_sysconfdir}/selinux/%{polname1}/users/local.users
|
|
||||||
make NAME=%{polname1} TYPE=%{type1} DISTRO=%{distro} DIRECT_INITRC=%{direct_initrc} MONOLITHIC=%{monolithic} DESTDIR=$RPM_BUILD_ROOT $RPM_BUILD_ROOT%{_sysconfdir}/selinux/%{polname1}/users/system.users
|
|
||||||
make NAME=%{polname2} TYPE=%{type2} DISTRO=%{distro} DIRECT_INITRC=%{direct_initrc} MONOLITHIC=%{monolithic} base.pp
|
|
||||||
make NAME=%{polname2} TYPE=%{type2} DISTRO=%{distro} DIRECT_INITRC=%{direct_initrc} MONOLITHIC=%{monolithic} modules
|
|
||||||
%{__mkdir} -p $RPM_BUILD_ROOT/%{_usr}/share/selinux/%{polname2}/%{type2}
|
|
||||||
%{__cp} *.pp $RPM_BUILD_ROOT/%{_usr}/share/selinux/%{polname2}/%{type2}
|
|
||||||
%{__mkdir} -p $RPM_BUILD_ROOT/%{_sysconfdir}/selinux/%{polname2}/policy
|
|
||||||
%{__mkdir} -p $RPM_BUILD_ROOT/%{_sysconfdir}/selinux/%{polname2}/contexts/files
|
|
||||||
make NAME=%{polname2} TYPE=%{type2} DISTRO=%{distro} DIRECT_INITRC=%{direct_initrc} MONOLITHIC=y DESTDIR=$RPM_BUILD_ROOT install-appconfig
|
|
||||||
make NAME=%{polname2} TYPE=%{type2} DISTRO=%{distro} DIRECT_INITRC=%{direct_initrc} MONOLITHIC=%{monolithic} DESTDIR=$RPM_BUILD_ROOT $RPM_BUILD_ROOT%{_sysconfdir}/selinux/%{polname2}/users/local.users
|
|
||||||
make NAME=%{polname2} TYPE=%{type2} DISTRO=%{distro} DIRECT_INITRC=%{direct_initrc} MONOLITHIC=%{monolithic} DESTDIR=$RPM_BUILD_ROOT $RPM_BUILD_ROOT%{_sysconfdir}/selinux/%{polname2}/users/system.users
|
|
||||||
|
|
||||||
%clean
|
|
||||||
%{__rm} -fR $RPM_BUILD_ROOT
|
|
||||||
|
|
||||||
%files
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_sysconfdir}/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/*.pp
|
|
||||||
#%ghost %config(noreplace) %{_sysconfdir}/selinux/config
|
|
||||||
%dir %{_sysconfdir}/selinux/*
|
|
||||||
%ghost %config %{_sysconfdir}/selinux/*/booleans
|
|
||||||
%dir %{_sysconfdir}/selinux/*/policy
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/*/policy/policy.*
|
|
||||||
%dir %{_sysconfdir}/selinux/*/contexts
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/*/contexts/customizable_types
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/*/contexts/dbus_contexts
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/*/contexts/default_contexts
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/*/contexts/default_type
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/*/contexts/failsafe_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/*/contexts/initrc_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/*/contexts/removable_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/*/contexts/userhelper_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/*/contexts/x_contexts
|
|
||||||
%dir %{_sysconfdir}/selinux/*/contexts/files
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/*/contexts/files/file_contexts
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/*/contexts/files/homedir_template
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/*/contexts/files/file_contexts.homedirs
|
|
||||||
%config %{_sysconfdir}/selinux/*/contexts/files/media
|
|
||||||
%dir %{_sysconfdir}/selinux/*/users
|
|
||||||
%config %{_sysconfdir}/selinux/*/users/system.users
|
|
||||||
%config %{_sysconfdir}/selinux/*/users/local.users
|
|
||||||
#%ghost %dir %{_sysconfdir}/selinux/*/modules
|
|
||||||
|
|
||||||
%pre
|
|
||||||
|
|
||||||
%post
|
|
||||||
|
|
||||||
%package base-targeted
|
|
||||||
Summary: SELinux %{polname1} base policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
Provides: selinux-policy-base
|
|
||||||
|
|
||||||
%description base-targeted
|
|
||||||
SELinux Reference policy targeted base module.
|
|
||||||
|
|
||||||
%files base-targeted
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/%{polname1}
|
|
||||||
%dir %{_usr}/share/selinux/%{polname1}/%{type1}
|
|
||||||
%config %{_usr}/share/selinux/%{polname1}/%{type1}/base.pp
|
|
||||||
%dir %{_sysconfdir}/selinux
|
|
||||||
#%ghost %config(noreplace) %{_sysconfdir}/selinux/config
|
|
||||||
%dir %{_sysconfdir}/selinux/%{polname1}
|
|
||||||
%ghost %config %{_sysconfdir}/selinux/%{polname1}/booleans
|
|
||||||
%dir %{_sysconfdir}/selinux/%{polname1}/policy
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/%{polname1}/policy/policy.*
|
|
||||||
%dir %{_sysconfdir}/selinux/%{polname1}/contexts
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname1}/contexts/customizable_types
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname1}/contexts/dbus_contexts
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname1}/contexts/default_contexts
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname1}/contexts/default_type
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname1}/contexts/failsafe_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname1}/contexts/initrc_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname1}/contexts/removable_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname1}/contexts/userhelper_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname1}/contexts/x_contexts
|
|
||||||
%dir %{_sysconfdir}/selinux/%{polname1}/contexts/files
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/%{polname1}/contexts/files/file_contexts
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/%{polname1}/contexts/files/homedir_template
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/%{polname1}/contexts/files/file_contexts.homedirs
|
|
||||||
%config %{_sysconfdir}/selinux/%{polname1}/contexts/files/media
|
|
||||||
%dir %{_sysconfdir}/selinux/%{polname1}/users
|
|
||||||
%config %{_sysconfdir}/selinux/%{polname1}/users/system.users
|
|
||||||
%config %{_sysconfdir}/selinux/%{polname1}/users/local.users
|
|
||||||
#%ghost %dir %{_sysconfdir}/selinux/%{polname1}/modules
|
|
||||||
|
|
||||||
%post base-targeted
|
|
||||||
semodule -b /usr/share/selinux/%{polname1}/%{type1}/base.pp -s %{_sysconfdir}/selinux/%{polname1}
|
|
||||||
for file in $(ls /usr/share/selinux/%{polname1}/%{type1} | grep -v base.pp)
|
|
||||||
do semodule -i /usr/share/selinux/%{polname1}/%{type1}/$file -s %{_sysconfdir}/selinux/%{polname1}
|
|
||||||
done
|
|
||||||
|
|
||||||
%package base-strict
|
|
||||||
Summary: SELinux %{polname2} base policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
Provides: selinux-policy-base
|
|
||||||
|
|
||||||
%description base-strict
|
|
||||||
SELinux Reference policy strict base module.
|
|
||||||
|
|
||||||
%files base-strict
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/%{polname2}
|
|
||||||
%dir %{_usr}/share/selinux/%{polname2}/%{type2}
|
|
||||||
%config %{_usr}/share/selinux/%{polname2}/%{type2}/base.pp
|
|
||||||
%dir %{_sysconfdir}/selinux
|
|
||||||
#%ghost %config(noreplace) %{_sysconfdir}/selinux/config
|
|
||||||
%dir %{_sysconfdir}/selinux/%{polname2}
|
|
||||||
%ghost %config %{_sysconfdir}/selinux/%{polname2}/booleans
|
|
||||||
%dir %{_sysconfdir}/selinux/%{polname2}/policy
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/%{polname2}/policy/policy.*
|
|
||||||
%dir %{_sysconfdir}/selinux/%{polname2}/contexts
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname2}/contexts/customizable_types
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname2}/contexts/dbus_contexts
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname2}/contexts/default_contexts
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname2}/contexts/default_type
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname2}/contexts/failsafe_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname2}/contexts/initrc_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname2}/contexts/removable_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname2}/contexts/userhelper_context
|
|
||||||
%config(noreplace) %{_sysconfdir}/selinux/%{polname2}/contexts/x_contexts
|
|
||||||
%dir %{_sysconfdir}/selinux/%{polname2}/contexts/files
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/%{polname2}/contexts/files/file_contexts
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/%{polname2}/contexts/files/homedir_template
|
|
||||||
#%ghost %config %{_sysconfdir}/selinux/%{polname2}/contexts/files/file_contexts.homedirs
|
|
||||||
%config %{_sysconfdir}/selinux/%{polname2}/contexts/files/media
|
|
||||||
%dir %{_sysconfdir}/selinux/%{polname2}/users
|
|
||||||
%config %{_sysconfdir}/selinux/%{polname2}/users/system.users
|
|
||||||
%config %{_sysconfdir}/selinux/%{polname2}/users/local.users
|
|
||||||
#%ghost %dir %{_sysconfdir}/selinux/%{polname2}/modules
|
|
||||||
|
|
||||||
%post base-strict
|
|
||||||
semodule -b /usr/share/selinux/%{polname2}/%{type2}/base.pp -s %{_sysconfdir}/selinux/%{polname2}
|
|
||||||
for file in $(ls /usr/share/selinux/%{polname2}/%{type2} | grep -v base.pp)
|
|
||||||
do semodule -i /usr/share/selinux/%{polname2}/%{type2}/$file -s %{_sysconfdir}/selinux/%{polname2}
|
|
||||||
done
|
|
||||||
|
|
||||||
%package apache
|
|
||||||
Summary: SELinux apache policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
Requires: selinux-policy-base
|
|
||||||
|
|
||||||
%description apache
|
|
||||||
SELinux Reference policy apache module.
|
|
||||||
|
|
||||||
%files apache
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/apache.pp
|
|
||||||
|
|
||||||
%post apache
|
|
||||||
if [ -d %{_sysconfdir}/selinux/%{polname1}/modules ] ; then
|
|
||||||
semodule -n -i %{_usr}/share/selinux/%{polname1}/%{type1}/apache.pp -s %{_sysconfdir}/selinux/%{polname1}
|
|
||||||
fi
|
|
||||||
if [ -d %{_sysconfdir}/selinux/%{polname2}/modules ] ; then
|
|
||||||
semodule -i %{_usr}/share/selinux/%{polname2}/%{type2}/apache.pp -s %{_sysconfdir}/selinux/%{polname2}
|
|
||||||
fi
|
|
||||||
|
|
||||||
%preun apache
|
|
||||||
if [ -d %{_sysconfdir}/selinux/%{polname1}/modules ]
|
|
||||||
then semodule -n -r apache -s %{_sysconfdir}/selinux/%{polname1}
|
|
||||||
fi
|
|
||||||
if [ -d %{_sysconfdir}/selinux/%{polname2}/modules ]
|
|
||||||
then semodule -n -r apache -s %{_sysconfdir}/selinux/%{polname2}
|
|
||||||
fi
|
|
||||||
|
|
||||||
%package bind
|
|
||||||
Summary: SELinux bind policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
|
|
||||||
%description bind
|
|
||||||
SELinux Reference policy bind module.
|
|
||||||
|
|
||||||
%files bind
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/bind.pp
|
|
||||||
|
|
||||||
%post bind
|
|
||||||
semodule -i %{_usr}/share/selinux/targeted/targeted-mcs/bind.pp
|
|
||||||
|
|
||||||
%preun bind
|
|
||||||
semodule -r bind
|
|
||||||
|
|
||||||
%package dhcp
|
|
||||||
Summary: SELinux dhcp policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
|
|
||||||
%description dhcp
|
|
||||||
SELinux Reference policy dhcp module.
|
|
||||||
|
|
||||||
%files dhcp
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/dhcp.pp
|
|
||||||
|
|
||||||
%post dhcp
|
|
||||||
semodule -i %{_usr}/share/selinux/targeted/targeted-mcs/dhcp.pp
|
|
||||||
|
|
||||||
%preun dhcp
|
|
||||||
semodule -r dhcp
|
|
||||||
|
|
||||||
%package ldap
|
|
||||||
Summary: SELinux ldap policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
|
|
||||||
%description ldap
|
|
||||||
SELinux Reference policy ldap module.
|
|
||||||
|
|
||||||
%files ldap
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/ldap.pp
|
|
||||||
|
|
||||||
%post ldap
|
|
||||||
semodule -i %{_usr}/share/selinux/targeted/targeted-mcs/ldap.pp
|
|
||||||
|
|
||||||
%preun ldap
|
|
||||||
semodule -r ldap
|
|
||||||
|
|
||||||
%package mailman
|
|
||||||
Summary: SELinux mailman policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
|
|
||||||
%description mailman
|
|
||||||
SELinux Reference policy mailman module.
|
|
||||||
|
|
||||||
%files mailman
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/mailman.pp
|
|
||||||
|
|
||||||
%post mailman
|
|
||||||
semodule -i %{_usr}/share/selinux/targeted/targeted-mcs/mailman.pp
|
|
||||||
|
|
||||||
%preun mailman
|
|
||||||
semodule -r mailman
|
|
||||||
|
|
||||||
%package mysql
|
|
||||||
Summary: SELinux mysql policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
|
|
||||||
%description mysql
|
|
||||||
SELinux Reference policy mysql module.
|
|
||||||
|
|
||||||
%files mysql
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/mysql.pp
|
|
||||||
|
|
||||||
%post mysql
|
|
||||||
semodule -i %{_usr}/share/selinux/targeted/targeted-mcsmysql.pp
|
|
||||||
|
|
||||||
%preun mysql
|
|
||||||
semodule -r mysql
|
|
||||||
|
|
||||||
%package portmap
|
|
||||||
Summary: SELinux portmap policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
|
|
||||||
%description portmap
|
|
||||||
SELinux Reference policy portmap module.
|
|
||||||
|
|
||||||
%files portmap
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/portmap.pp
|
|
||||||
|
|
||||||
%post portmap
|
|
||||||
semodule -i %{_usr}/share/selinux/targeted/targeted-mcs/portmap.pp
|
|
||||||
|
|
||||||
%preun portmap
|
|
||||||
semodule -r portmap
|
|
||||||
|
|
||||||
%package postgresql
|
|
||||||
Summary: SELinux postgresql policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
|
|
||||||
%description postgresql
|
|
||||||
SELinux Reference policy postgresql module.
|
|
||||||
|
|
||||||
%files postgresql
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/postgresql.pp
|
|
||||||
|
|
||||||
%post postgresql
|
|
||||||
semodule -i %{_usr}/share/selinux/targeted/targeted-mcs/postgresql.pp
|
|
||||||
|
|
||||||
%preun postgresql
|
|
||||||
semodule -r postgresql
|
|
||||||
|
|
||||||
%package samba
|
|
||||||
Summary: SELinux samba policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
|
|
||||||
%description samba
|
|
||||||
SELinux Reference policy samba module.
|
|
||||||
|
|
||||||
%files samba
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/samba.pp
|
|
||||||
|
|
||||||
%post samba
|
|
||||||
semodule -i %{_usr}/share/selinux/targeted/targeted-mcs/samba.pp
|
|
||||||
|
|
||||||
%preun samba
|
|
||||||
semodule -r samba
|
|
||||||
|
|
||||||
%package snmp
|
|
||||||
Summary: SELinux snmp policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
|
|
||||||
%description snmp
|
|
||||||
SELinux Reference policy snmp module.
|
|
||||||
|
|
||||||
%files snmp
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/snmp.pp
|
|
||||||
|
|
||||||
%post snmp
|
|
||||||
semodule -i %{_usr}/share/selinux/targeted/targeted-mcs/snmp.pp
|
|
||||||
|
|
||||||
%preun snmp
|
|
||||||
semodule -r snmp
|
|
||||||
|
|
||||||
%package squid
|
|
||||||
Summary: SELinux squid policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
|
|
||||||
%description squid
|
|
||||||
SELinux Reference policy squid module.
|
|
||||||
|
|
||||||
%files squid
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/squid.pp
|
|
||||||
|
|
||||||
%post squid
|
|
||||||
semodule -i %{_usr}/share/selinux/targeted/targeted-mcs/squid.pp
|
|
||||||
|
|
||||||
%preun squid
|
|
||||||
semodule -r squid
|
|
||||||
|
|
||||||
%package webalizer
|
|
||||||
Summary: SELinux webalizer policy
|
|
||||||
Group: System Environment/Base
|
|
||||||
|
|
||||||
%description webalizer
|
|
||||||
SELinux Reference policy webalizer module.
|
|
||||||
|
|
||||||
%files webalizer
|
|
||||||
%defattr(-,root,root)
|
|
||||||
%dir %{_usr}/share/selinux
|
|
||||||
%dir %{_usr}/share/selinux/*
|
|
||||||
%dir %{_usr}/share/selinux/*/*
|
|
||||||
%config %{_usr}/share/selinux/*/*/webalizer.pp
|
|
||||||
|
|
||||||
%post webalizer
|
|
||||||
semodule -i %{_usr}/share/selinux/targeted/targeted-mcs/webalizer.pp
|
|
||||||
|
|
||||||
%preun webalizer
|
|
||||||
semodule -r webalizer
|
|
||||||
|
|
||||||
%changelog
|
|
@ -1,49 +0,0 @@
|
|||||||
%define type refpolicy
|
|
||||||
%define POLICYDIR /etc/selinux/%{type}
|
|
||||||
%define FILE_CON ${POLICYDIR}/contexts/files/file_contexts
|
|
||||||
%define FC_PRE ${FILE_CON}.pre
|
|
||||||
|
|
||||||
Summary: SELinux Reference Policy configuration source files
|
|
||||||
Name: selinux-refpolicy-sources
|
|
||||||
Version: REFPOL_VERSION
|
|
||||||
Release: 1
|
|
||||||
License: GPL
|
|
||||||
Group: System Environment/Base
|
|
||||||
PreReq: m4 make policycoreutils kernel gcc
|
|
||||||
Requires: checkpolicy >= 1.33.1
|
|
||||||
Requires: python make m4
|
|
||||||
BuildRequires: make m4 python
|
|
||||||
Obsoletes: policy-sources
|
|
||||||
Source: refpolicy-%{version}.tar.bz2
|
|
||||||
Url: http://oss.tresys.com/projects/refpolicy
|
|
||||||
BuildArch: noarch
|
|
||||||
BuildRoot: /tmp/rpmbuild/%{name}
|
|
||||||
|
|
||||||
%description
|
|
||||||
This subpackage includes the SELinux Reference Policy
|
|
||||||
source files, which can be used to build a targeted policy
|
|
||||||
or strict policy configuration.
|
|
||||||
|
|
||||||
%prep
|
|
||||||
%setup -q -n refpolicy
|
|
||||||
|
|
||||||
%build
|
|
||||||
sed -i -e '/^TYPE/s/strict/targeted/' Makefile
|
|
||||||
sed -i -e 's/^#DISTRO/DISTRO/' Makefile
|
|
||||||
sed -i -e '/^DIRECT_INITRC/s/n/y/' Makefile
|
|
||||||
make conf
|
|
||||||
make clean
|
|
||||||
rm -f support/*.pyc
|
|
||||||
|
|
||||||
%install
|
|
||||||
rm -fR $RPM_BUILD_ROOT
|
|
||||||
make DESTDIR=$RPM_BUILD_ROOT install-src
|
|
||||||
|
|
||||||
%clean
|
|
||||||
rm -fR $RPM_BUILD_ROOT
|
|
||||||
|
|
||||||
%files
|
|
||||||
%defattr(-,root,root,-)
|
|
||||||
%{_sysconfdir}/selinux/%{type}/src/policy/
|
|
||||||
|
|
||||||
%changelog
|
|
@ -1,11 +0,0 @@
|
|||||||
# Read booleans.conf and output M4 directives to
|
|
||||||
# override default settings in global_booleans
|
|
||||||
|
|
||||||
BEGIN {
|
|
||||||
FS="="
|
|
||||||
}
|
|
||||||
|
|
||||||
/^[[:blank:]]*[[:alpha:]]+/{
|
|
||||||
gsub(/[[:blank:]]*/,"")
|
|
||||||
print "define(`"$1"_conf',`"$2"')"
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
divert
|
|
@ -1,5 +0,0 @@
|
|||||||
user root prefix staff;
|
|
||||||
user staff_u prefix staff;
|
|
||||||
user user_u prefix user;
|
|
||||||
user sysadm_u prefix sysadm;
|
|
||||||
user secadm_u prefix secadm;
|
|
@ -1,2 +0,0 @@
|
|||||||
user root prefix user;
|
|
||||||
user user_u prefix user;
|
|
Loading…
Reference in New Issue
Block a user