pax_global_header00006660000000000000000000000064123322160630014510gustar00rootroot0000000000000052 comment=1e6482134b9dc2e4480a1cecaf1d366c9d42b0e7 policycoreutils-2.3/000077500000000000000000000000001233221606300146055ustar00rootroot00000000000000policycoreutils-2.3/.gitignore000066400000000000000000000005611233221606300165770ustar00rootroot00000000000000load_policy/load_policy newrole/newrole restorecond/restorecond run_init/open_init_pty run_init/run_init secon/secon semodule/semodule semodule_deps/semodule_deps semodule_expand/semodule_expand semodule_link/semodule_link semodule_package/semodule_package semodule_package/semodule_unpackage sestatus/sestatus setfiles/restorecon setfiles/setfiles setsebool/setsebool policycoreutils-2.3/.tx/000077500000000000000000000000001233221606300153165ustar00rootroot00000000000000policycoreutils-2.3/.tx/config000066400000000000000000000002471233221606300165110ustar00rootroot00000000000000[main] host = https://www.transifex.com [policycoreutils.policycoreutils] file_filter = po/.po source_file = po/policycoreutils.pot source_lang = en type = PO policycoreutils-2.3/COPYING000066400000000000000000000431311233221606300156420ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. policycoreutils-2.3/ChangeLog000066400000000000000000001420021233221606300163560ustar00rootroot000000000000002.3 2014-05-06 * Add -P semodule option to man page from Dan Walsh. * selinux_current_policy_path will return none on a disabled SELinux system from Dan Walsh. * Add new icons for sepolicy gui from Dan Walsh. * Only return writeable files that are enabled from Dan Walsh. * Add domain to short list of domains, when -t and -d from Dan Walsh. * Fix up desktop files to match current standards from Dan Walsh. * Add support to return sensitivities and categories for python from Dan Walsh. * Cleanup whitespace from Dan Walsh. * Add message to tell user to install sandbox policy from Dan Walsh. * Add systemd unit file for mcstrans from Laurent Bigonville. * Improve restorecond systemd unit file from Laurent Bigonville. * Minor man pages improvements from Laurent Bigonville. 2.2.5 2013-12-09 * Ignore selevel/serange if MLS is disabled from Sven Vermeulen. 2.2.4 2013-11-26 * Revert automatic setting of serange and seuser in seobject; was breaking non-MLS systems. 2.2.3 2013-11-13 * Apply polkit check on all dbus interfaces and restrict to active user from Dan Walsh. * Fix typo in sepolicy gui dbus.relabel_on_boot call from Dan Walsh. 2.2.2 2013-11-06 * Remove import policycoreutils.default_encoding_utf8 from semanage from Dan Walsh. 2.2.1 2013-10-31 * Make yum/extract_rpms optional for sepolicy generate from Dan Walsh. * Add test suite for audit2allow and sepolgen-ifgen from Dan Walsh. 2.2 2013-10-30 * Properly build the swig exception file from Laurent Bigonville. * Fix man pages from Laurent Bigonville. * Support overriding PATH and INITDIR in Makefile from Laurent Bigonville. * Fix LDFLAGS usage from Laurent Bigonville. * Fix init_policy warning from Laurent Bigonville. * Fix semanage logging from Laurent Bigonville. * Open newrole stdin as read/write from Sven Vermeulen. * Fix sepolicy transition from Sven Vermeulen. * Support overriding CFLAGS from Simon Ruderich. * Create correct man directory for run_init from Russell Coker. * restorecon GLOB_BRACE change from Michal Trunecka. * Extend audit2why to report additional constraint information. * Catch IOError errors within audit2allow from Dan Walsh. * semanage export/import fixes from Dan Walsh. * Improve setfiles progress reporting from Dan Walsh. * Document setfiles -o option in usage from Dan Walsh. * Change setfiles to always return -1 on failure from Dan Walsh. * Improve setsebool error r eporting from Dan Walsh. * Major overhaul of gui from Dan Walsh. * Fix sepolicy handling of non-MLS policy from Dan Walsh. * Support returning type aliases from Dan Walsh. * Add sepolicy tests from Dan Walsh. * Add org.selinux.config.policy from Dan Walsh. * Improve range and user input checking by semanage from Dan Walsh. * Prevent source or target arguments that end with / for substitutions from Dan Walsh. * Allow use of <> for semanage fcontext from Dan Walsh. * Report customized user levels from Dan Walsh. * Support deleteall for restoring disabled modules from Dan Walsh. * Improve semanage error reporting from Dan Walsh. * Only list disabled modules for module locallist from Dan Walsh. * Fix logging from Dan Walsh. * Define new constants for file type character codes from Dan Walsh. * Improve bash completions from Dan Walsh. * Convert semanage to argparse from Dan Walsh (originally by Dave Quigley). * Add semanage tests from Dan Walsh. * Split semanage man pages from Dan Walsh. * Move bash completion scripts from Dan Walsh. * Replace genhomedircon script with a link to semodule from Dan Walsh. * Fix fixfiles from Dan Walsh. * Add support for systemd service for restorecon from Dan Walsh. * Spelling corrections from Dan Walsh. * Improve sandbox support for home dir symlinks and file caps from Dan Walsh. * Switch sandbox to openbox window manager from Dan Walsh. * Coalesce audit2why and audit2allow from Dan Walsh. * Change audit2allow to append to output file from Dan Walsh. * Update translations from Dan Walsh. * Change audit2why to use selinux_current_policy_path from Dan Walsh. 2.1.14 2013-02-01 * setfiles: estimate percent progress * load_policy: make link at the destination directory * Rebuild polgen.glade with glade-3 * sepolicy: new command to unite small utilities * sepolicy: Update Makefiles and po files * sandbox: use sepolicy to look for sandbox_t * gui: switch to use sepolicy * gui: sepolgen: use sepolicy to generate * semanage: use sepolicy for boolean dictionary * add po file configuration information * po: stop running update-po on all * semanage: seobject verify policy types before allowing you to assign them. * gui: Start using Popen, instead of os.spawnl * sandbox: Copy /var/tmp to /tmp as they are the same inside * qualifier to shred content * semanage: Fix handling of boolean_sub names when using the -F flag * semanage: man: roles instead of role * gui: system-config-selinux: Catch no DISPLAY= error * setfiles: print error if no default label found * semanage: list logins file entries in semanage login -l * semanage: good error message is sepolgen python module missing * gui: system-config-selinux: do not use lokkit * secon: add support for setrans color information in prompt output * restorecond: remove /etc/mtab from default list * gui: If you are not able to read enforcemode set it to False * genhomedircon: regenerate genhomedircon more often * restorecond: Add /etc/udpatedb.conf to restorecond.conf * genhomedircon generation to allow spec file to pass in SEMODULE_PATH * fixfiles: relabel only after specific date * po: update translations * sandbox: seunshare: do not reassign realloc value * seunshare: do checking on setfsuid * sestatus: rewrite to shut up coverity 2.1.13 2012-09-13 * genhomedircon: manual page improvements * setfiles/restorecon minor improvements * run_init: If open_init_pty is not available then just use exec * newrole: do not drop capabilities when newrole is run as * restorecon: only update type by default * scripts: Don't syslog setfiles changes on a fixfiles restore * setfiles: do not syslog if no changes * Disable user restorecond by default * Make restorecon return 0 when a file has changed context * setfiles: Fix process_glob error handling * semanage: allow enable/disable under -m * add .tx to gitignore * translations: commit translations from Fedora community * po: silence build process * gui: Checking in policy to support polgengui and sepolgen. * gui: polgen: search for systemd subpackage when generating policy * gui: for exploring booleans * gui: system-config-selinux gui * Add Makefiles to support new gui code * gui: remove lockdown wizard * return equivalency records in fcontext customized * semanage: option to not load new policy into kernel after * sandbox: manpage update to describe standard types * setsebool: -N should not reload policy on changes * semodule: Add -N qualifier to no reload kernel policy * gui: polgen: sort selinux types of user controls * gui: polgen: follow symlinks and get the real path to * gui: Fix missing error function * setfiles: return errors when bad paths are given * fixfiles: tell restorecon to ignore missing paths * setsebool: error when setting multiple options * semanage: use boolean subs. * sandbox: Make sure Xephyr never listens on tcp ports * sepolgen: return and output constraint violation information * semanage: skip comments while reading external configuration files * restorecond: relabel all mount runtime files in the restorecond example * genhomedircon: dynamically create genhomedircon 2.1.12 2012-06-28 * restorecond: wrong options should exit with non-zero error code * restorecond: Add -h option to get usage command * resorecond: user: fix fd leak * mcstrans: add -f to run in foreground * semanage: fix man page range and level defaults * semanage: bash completion for modules should include -a,-m, -d * semanage: manpage update for -e * semanage: dontaudit off should work * semanage: locallist option does not take an argument * sepolgen: Make use of setools optional within sepolgen 2.1.11 2012-03-28 * sandbox: do not propogate inside mounts outside * sandbox: Removing sandbox init script, should no longer be necessary * restorecond: Stop using deprecated interfaces for g_io * semanage: proper auditting of user changes for LSPP * semanage: audit message to show what record(s) and item(s) have chaged * scripts: Update Makefiles to handle /usrmove * mcstrans: Version should have been bumped on last check in * seunshare: Only drop caps not the Bounding Set from seunshare * Add bash-completion scripts for setsebool and semanage * newrole: Use correct capng calls in newrole * Fix infinite loop with inotify on 2.6.31 kernels * fix ftbfs with hardening flags * Only run setfiles if we found read-write filesystems to run it on * update .po files * remove empty po files * do not fail to install if unable to make load_policy lnk file 2.1.10 2011-12-21 * Remove excess whitespace * sandbox: Add back in . functions to sandbox.init script * Fix Makefile to match other policycoreutils Makefiles * semanage: drop unused translation getopt 2.1.9 2011-12-05 * sandbox: move sandbox.conf.5 to just sandbox.5 * po: Makefile use -p to preserve times to allow multilib simultatious installs * of po files * sandbox: Allow user to specify the DPI value for X in a sandbox * sandbox: make sure the domain launching sandbox has at least 100 categories * sandbox: do not try forever to find available category set * sandbox: only complain if sandbox unable to launch * sandbox: init script run twice is still successful * semanage: print local and dristo equiv rules * semanage: check file equivalence rules for conflict * semanage: Make sure semanage fcontext -l -C prints even if local keys * are not defined * semanage: change src,dst to target,substitute for equivalency * sestatus: Updated sestatus and man pages. * Added SELinux config file man page. * add clean target to man Makefile 2.1.8 2011-11-03 * sandbox: Maintain the LANG environment into the sandbox * audit2allow: use audit2why internally * fixfiles: label /root but not /var/lib/BackupPC * semanage: update local boolean settings is dealing with localstore * semanage: missing modify=True * semanage: set modified correctly * restorecond: make restorecond dbuss-able * restorecon: Always check return code on asprintf * restorecond: make restorecond -u exit when terminal closes * sandbox: introduce package name and language stuff * semodule_package: remove semodule_unpackage on clean * fix sandbox Makefile to support DESTDIR * semanage: Add -o description to the semanage man page * make use of the new realpath_not_final function * setfiles: close /proc/mounts file when finished * semodule: Document semodule -p in man page * setfiles: fix use before initialized * restorecond: Add .local/share as a directory to watch 2.1.7 2011-09-27 * semanage: fix indentation error in seobject 2.1.6 2011-09-15 * sepolgen-ifgen: new attr-helper does something * audit2allow: use alternate policy file * audit2allow: sepolgen-ifgen use the attr helper * setfiles: switch from stat to stat64 * setfiles: Fix potential crash using dereferenced ftsent * setfiles: do not wrap * output at 80 characters * sandbox: add -Wall and -Werror to makefile * sandbox: add sandbox cgroup support * sandbox: rewrite /tmp handling * sandbox: do not bind mount so much * sandbox: add level based kill option * sandbox: cntrl-c should kill entire process control group * Create a new preserve_tunables flag in sepol_handle_t. * semanage: show running and disk setting for booleans * semanage: Dont print heading if no items selected * sepolgen: audit2allow is mistakakenly not allowing valid module names * semanage: Catch RuntimeErrors, that can be generated when SELinux is disabled * More files to ignore * tree: default make target to all not install * sandbox: do not load unused generic init functions 2.1.5 2011-08-26 * setfiles: Fix process_glob to handle error situations * sandbox: Allow seunshare to run as root * sandbox: trap sigterm to make sure sandbox * sandbox: pass DPI from the desktop * sandbox: seunshare: introduce helper spawn_command * sandbox: seunshare: introduce new filesystem helpers * sandbox: add -C option to not drop * sandbox: split seunshare caps dropping * sandbox: use dbus-launch * sandbox: numerous simple updates to sandbox * sandbox: do not require selinux context * sandbox: Makefile: new man pages * sandbox: rename dir to srcdir * sandbox: allow users specify sandbox window size * sandbox: check for paths up front * sandbox: use defined values for paths rather * sandbox: move seunshare globals to the top * sandbox: whitespace fix * semodule_package: Add semodule_unpackage executable * setfiles: get rid of some stupid globals * setfiles: move exclude_non_seclabel_mounts to a generic location 2.1.4 2011-08-17 * run_init: clarification of the usage in the * semanage: fix usage header around booleans * semanage: remove useless empty lines * semanage: update man page with new examples * semanage: update usage text * semanage: introduce file context equivalencies * semanage: enable and disable modules * semanage: output all local modifications * semanage: introduce extraction of local configuration * semanage: cleanup error on invalid operation * semanage: handle being called with no arguments * semanage: return sooner to save CPU time * semanage: surround getopt with try/except * semanage: use define/raise instead of lots of * semanage: some options are only valid for * semanage: introduce better deleteall support * semanage: do not allow spaces in file * semanage: distinguish between builtin and local permissive * semanage: centralized ip node handling * setfiles: make the restore function exclude() non-static * setfiles: use glob to handle ~ and * fixfiles: do not hard code types * fixfiles: stop trying to be smart about * fixfiles: use new kernel seclabel option * fixfiles: pipe everything to cat before sending * fixfiles: introduce /etc/selinux/fixfiles_exclude_dirs * semodule: support for alternative root paths 2.1.3 2011-08-03 * semanage: fix indention * semodule_package: fix man page typo * semodule_expand: update man page with -a * semanage: handle os errors * semanage: fix traceback with bad options * semanage: show usage on -h or --help * semanage: introduce more deleteall options * semanage: verify ports < 65536 * transaction into semanageRecords * make get_handle a method of semanageRecords * remove a needless blank line * make process_one error if not initialized correctly * fixfiles: correct usage for r_opts.rootpath * put -p in help for restorecon and * fixfiles: do not try to only label * fixfiles clean up /var/run and /var/lib/debug * fixfiles delete tmp sockets and pipes rather * fixfile use find -delete instead of pipe * chcat man page typo * add man page for genhomedircon * setfiles fix typo * setsebool should inform users they need to * setsebool typos * open_init_tty man page typos * Don't add user site directory to sys.path * newrole retain CAP_SETPCAP 2.1.2 2011-08-02 * seunshare: define _GNU_SOURCE earlier * make ignore_enoent do something * restorecond: first user logged in is not noticed * Repo: update .gitignore 2.1.1 2011-08-01 * Man page updates * restorecon fix for bad inotify assumptions 2.1.0 2011-07-27 * Release, minor version bump 2.0.86 2011-04-11 * Use correct color range in mcstrand by Richard Haines. 2.0.85 2010-12-20 * Move newrole to use libcap-ng from Dan Walsh 2.0.84 2010-11-16 * Add mcstrans support from Ted Toth with modifications from Steve Lawrence. 2.0.83 2010-06-10 * Add sandbox support from Dan Walsh with modifications from Steve Lawrence. 2.0.82 2010-03-12 * Add avc's since boot from Dan Walsh. 2.0.81 2010-03-12 * Add dontaudit flag to audit2allow from Dan Walsh. 2.0.80 2010-03-06 * Module enable/disable support from Dan Walsh. 2.0.79 2010-01-26 * Fix double-free in newrole 2.0.78 2009-11-27 * Remove non-working OUTFILE from fixfiles from Dan Walsh. * Additional exception handling in chcat from Dan Walsh. 2.0.77 2009-11-19 * Fixed bug preventing semanage node -a from working from Chad Sellers * Fixed bug preventing semanage fcontext -l from working from Chad Sellers 2.0.76 2009-11-18 * Remove setrans management from semanage, as it does not work from Dan Walsh. * Move load_policy from /usr/sbin to /sbin from Dan Walsh. 2.0.75 2009-11-02 * Factor out restoring logic from setfiles.c into restore.c 2.0.74 2009-09-16 * Change semodule upgrade behavior to install even if the module is not present from Dan Walsh. * Make setfiles label if selinux is disabled and a seclabel aware kernel is running from Caleb Case. * Clarify forkpty() error message in run_init from Manoj Srivastava. 2.0.73 2009-09-04 * Add semanage dontaudit to turn off dontaudits from Dan Walsh. * Fix semanage to set correct mode for setrans file from Dan Walsh. * Fix malformed dictionary in portRecord from Dan Walsh. 2.0.72 2009-09-03 * Restore symlink handling support to restorecon based on a patch by Martin Orr. This fixes the restorecon /dev/stdin performed by Debian udev scripts that was broken by policycoreutils 2.0.70. 2.0.71 2009-08-11 * Modify setfiles/restorecon checking of exclude paths. Only check user-supplied exclude paths (not automatically generated ones based on lack of seclabel support), don't require them to be directories, and ignore permission denied errors on them (it is ok to exclude a path to which the caller lacks permission). 2.0.70 2009-08-04 * Modify restorecon to only call realpath() on user-supplied pathnames from Stephen Smalley. 2.0.69 2009-07-30 * Fix typo in fixfiles that prevented it from relabeling btrfs filesystems from Dan Walsh. 2.0.68 2009-07-24 * Modify setfiles to exclude mounts without seclabel option in /proc/mounts on kernels >= 2.6.30 from Thomas Liu. 2.0.67 2009-07-07 * Re-enable disable_dontaudit rules upon semodule -B from Christopher Pardy and Dan Walsh. 2.0.66 2009-07-07 * setfiles converted to fts from Thomas Liu. 2.0.65 2009-06-24 * Remove gui from po/Makefile and po/POTFILES and regenerate po files 2.0.64 2009-06-22 * Keep setfiles from spamming console from Dan Walsh. * Fix chcat's category expansion for users from Dan Walsh. 2.0.63 2009-05-15 * Fix transaction checking from Dan Walsh. * Make fixfiles -R (for rpm) recursive. * Make semanage permissive clean up after itself from Dan Walsh. * add /root/.ssh/* to restorecond.conf 2.0.62 2009-02-19 * Add btrfs to fixfiles from Dan Walsh. * Remove restorecond error for matching globs with multiple hard links and fix some error messages from Dan Walsh. * Make removing a non-existant module a warning rather than an error from Dan Walsh. * Man page fixes from Dan Walsh. 2.0.61 2009-01-12 * chcat: cut categories at arbitrary point (25) from Dan Walsh * semodule: use new interfaces in libsemanage for compressed files from Dan Walsh * audit2allow: string changes for usage 2.0.60 2008-11-12 * semanage: use semanage_mls_enabled() from Stephen Smalley. 2.0.59 2008-11-11 * fcontext add checked local records twice, fix from Dan Walsh. 2.0.58 2008-11-09 * Allow local file context entries to override policy entries in semanage from Dan Walsh. * Newrole error message corrections from Dan Walsh. * Add exception to audit2why call in audit2allow from Dan Walsh. 2.0.57 2008-09-18 * Update po files from Dan Walsh. 2.0.56 2008-09-12 * fixfiles will now remove all files in /tmp and will check for unlabeled_t in /tmp and /var/tmp from Dan Walsh. * add glob support to restorecond from Dan Walsh. * allow semanage to handle multi-line commands in a single transaction from Dan Walsh. 2.0.55 2008-08-26 * Merged semanage node support from Christian Kuester. 2.0.54 2008-08-05 * Add support for boolean files and group support for seusers from Dan Walsh. * Ensure that setfiles -p output is newline terminated from Russell Coker. 2.0.53 2008-07-29 * Change setfiles to validate all file_contexts files when using -c from Stephen Smalley. 2.0.52 2008-07-02 * Add permissive domain capability to semanage from Dan Walsh. 2.0.51 2008-06-28 * Add onboot option to fixfiles from Dan Walsh. * Change restorecon.init to not run on boot by default from Dan Walsh. 2.0.50 2008-06-30 * Fix audit2allow generation of role-type rules from Karl MacMillan. 2.0.49 2008-05-16 * Remove security_check_context calls for prefix validation from semanage. 2.0.48 2008-05-16 * Change setfiles and restorecon to not relabel if the file already has the correct context value even if -F/force is specified. 2.0.47 2008-04-18 * Update semanage man page for booleans from Dan Walsh. * Add further error checking to seobject.py for setting booleans. 2.0.46 2008-03-18 * Update audit2allow to report dontaudit cases from Dan Walsh. 2.0.45 2008-03-18 * Fix semanage port to use --proto from Caleb Case. 2.0.44 2008-02-22 * Fixed semodule to correctly handle error when unable to create a handle. 2.0.43 2008-02-08 * Merged fix fixfiles option processing from Vaclav Ovsik. 2.0.42 2008-02-02 * Make semodule_expand use sepol_set_expand_consume_base to reduce peak memory usage. 2.0.41 2008-01-28 * Merged audit2why fix and semanage boolean --on/--off/-1/-0 support from Dan Walsh. 2.0.40 2008-01-25 * Merged a second fixfiles -C fix from Marshall Miller. 2.0.39 2008-01-24 * Merged fixfiles -C fix from Marshall Miller. 2.0.38 2008-01-24 * Merged audit2allow cleanups and boolean descriptions from Dan Walsh. * Merged setfiles -0 support by Benny Amorsen via Dan Walsh. * Merged fixfiles fixes and support for ext4 and gfs2 from Dan Walsh. 2.0.37 2008-01-23 * Merged replacement for audit2why from Dan Walsh. 2.0.36 2008-01-23 * Merged update to chcat, fixfiles, and semanage scripts from Dan Walsh. 2.0.35 2007-12-21 * Merged support for non-interactive newrole command invocation from Tim Reed. 2.0.34 2007-12-14 * Update Makefile to not build restorecond if /usr/include/sys/inotify.h is not present 2.0.33 2007-12-07 * Drop verbose output on fixfiles -C from Dan Walsh. * Fix argument handling in fixfiles from Dan Walsh. * Enhance boolean support in semanage, including using the .xml description when available, from Dan Walsh. 2.0.32 2007-10-16 * load_policy initial load option from Chad Sellers. 2.0.31 2007-10-15 * Fix semodule option handling from Dan Walsh. 2.0.30 2007-10-11 * Add deleteall support for ports and fcontexts in semanage from Dan Walsh. 2.0.29 2007-10-05 * Add genhomedircon script to invoke semodule -Bn from Dan Walsh. 2.0.28 2007-10-05 * Update semodule man page for -D from Dan Walsh. * Add boolean, locallist, deleteall, and store support to semanage from Dan Walsh. 2.0.27 2007-09-19 * Improve semodule reporting of system errors from Stephen Smalley. 2.0.26 2007-09-18 * Fix setfiles selabel option flag setting for 64-bit from Stephen Smalley. 2.0.25 2007-08-23 * Remove genhomedircon script (functionality is now provided within libsemanage) from Todd Miller. 2.0.24 2007-08-23 * Fix genhomedircon searching for USER from Todd Miller * Install run_init with mode 0755 from Dan Walsh. * Fix chcat from Dan Walsh. * Fix fixfiles pattern expansion and error reporting from Dan Walsh. * Optimize genhomedircon to compile regexes once from Dan Walsh. * Fix semanage gettext call from Dan Walsh. 2.0.23 2007-08-16 * Disable dontaudits via semodule -D 2.0.22 2007-06-20 * Rebase setfiles to use new labeling interface. 2.0.21 2007-06-13 * Fixed setsebool (falling through to error path on success). 2.0.20 2007-06-05 * Merged genhomedircon fixes from Dan Walsh. * Merged setfiles -c usage fix from Dan Walsh. * Merged restorecon fix from Yuichi Nakamura. * Dropped -lsepol where no longer needed. 2.0.19 2007-05-11 * Merge newrole support for alternate pam configs from Ted X Toth. 2.0.18 2007-05-11 * Merged merging of restorecon into setfiles from Stephen Smalley. 2.0.17 2007-05-09 * Merged genhomedircon fix to find conflicting directories correctly from Dan Walsh. 2.0.16 2007-05-03 * Merged support for modifying the prefix via semanage from Dan Walsh. 2.0.15 2007-04-26 * Merged move of audit2why to /usr/bin from Dan Walsh. 2.0.14 2007-04-25 * Build fix for setsebool. 2.0.13 2007-04-24 * Merged setsebool patch to only use libsemanage for persistent boolean changes from Stephen Smalley. 2.0.12 2007-04-24 * Merged genhomedircon patch to use the __default__ setting from Dan Walsh. 2.0.11 2007-04-24 * Dropped -b option from load_policy in preparation for always preserving booleans across reloads in the kernel. 2.0.10 2007-04-24 * Merged chcat, fixfiles, genhomedircon, restorecond, and restorecon patches from Dan Walsh. 2.0.9 2007-04-12 * Merged seobject setransRecords patch to return the first alias from Xavier Toth. 2.0.8 2007-04-10 * Merged updates to sepolgen-ifgen from Karl MacMillan. 2.0.7 2007-03-01 * Merged restorecond init script LSB compliance patch from Steve Grubb. 2.0.6 2007-02-22 * Merged newrole O_NONBLOCK fix from Linda Knippers. 2.0.5 2007-02-22 * Merged sepolgen and audit2allow patches to leave generated files in the current directory from Karl MacMillan. 2.0.4 2007-02-22 * Merged restorecond memory leak fix from Steve Grubb. 2.0.3 2007-02-21 * Merged translations update from Dan Walsh. * Merged chcat fixes from Dan Walsh. * Merged man page fixes from Dan Walsh. * Merged seobject prefix validity checking from Dan Walsh. 2.0.2 2007-02-20 * Merged seobject exception handler fix from Caleb Case. * Merged setfiles memory leak patch from Todd Miller. 2.0.1 2007-02-08 * Merged small fix to correct include of errcodes.h in semodule_deps from Dan Walsh. 2.0.0 2007-02-05 * Merged new audit2allow from Karl MacMillan. This audit2allow depends on the new sepolgen python module. Note that you must run the sepolgen-ifgen tool to generate the data needed by audit2allow to generate refpolicy. 1.34.1 2007-01-22 * Fixed newrole non-pam build. 1.34.0 2007-01-18 * Updated version for stable branch. 1.33.16 2007-01-18 * Merged po file updates from Dan Walsh. * Removed update-po from all target in po/Makefile. 1.33.15 2007-01-17 * Merged unicode-to-string fix for seobject audit from Dan Walsh. * Merged man page updates to make "apropos selinux" work from Dan Walsh. 1.33.14 2007-01-16 * Merged newrole man page patch from Michael Thompson. 1.33.13 2007-01-16 * Merged patch to fix python unicode problem from Dan Walsh. 1.33.12 2007-01-11 * Merged newrole securetty check from Dan Walsh. * Merged semodule patch to generalize list support from Karl MacMillan. 1.33.11 2007-01-09 * Merged fixfiles and seobject fixes from Dan Walsh. * Merged semodule support for list of modules after -i from Karl MacMillan. 1.33.10 2007-01-08 * Merged patch to correctly handle a failure during semanage handle creation from Karl MacMillan. 1.33.9 2007-01-05 * Merged patch to fix seobject role modification from Dan Walsh. 1.33.8 2007-01-04 * Merged patches from Dan Walsh to: - omit the optional name from audit2allow - use the installed python version in the Makefiles - re-open the tty with O_RDWR in newrole 1.33.7 2007-01-03 * Patch from Dan Walsh to correctly suppress warnings in load_policy. 1.33.6 2006-11-29 * Patch from Dan Walsh to add an pam_acct_msg call to run_init * Patch from Dan Walsh to fix error code returns in newrole * Patch from Dan Walsh to remove verbose flag from semanage man page * Patch from Dan Walsh to make audit2allow use refpolicy Makefile in /usr/share/selinux/ 1.33.5 2006-11-27 * Merged patch from Michael C Thompson to clean up genhomedircon error handling. 1.33.4 2006-11-21 * Merged po file updates from Dan Walsh. 1.33.3 2006-11-21 * Merged setsebool patch from Karl MacMillan. This fixes a bug reported by Yuichi Nakamura with always setting booleans persistently on an unmanaged system. 1.33.2 2006-11-20 * Merged patch from Dan Walsh (via Karl MacMillan): * Added newrole audit message on login failure * Add /var/log/wtmp to restorecond.conf watch list * Fix genhomedircon, semanage, semodule_expand man pages. 1.33.1 2006-11-13 * Merged newrole patch set from Michael Thompson. 1.32 2006-10-17 * Updated version for release. 1.30.31 2006-10-17 * Merged audit2allow -l fix from Yuichi Nakamura. * Merged restorecon -i and -o - support from Karl MacMillan. * Merged semanage/seobject fix from Dan Walsh. * Merged fixfiles -R and verify changes from Dan Walsh. 1.30.30 2006-09-29 * Merged newrole auditing of failures due to user actions from Michael Thompson. 1.30.29 2006-09-13 * Man page corrections from Dan Walsh * Change all python invocations to /usr/bin/python -E * Add missing getopt flags to genhomedircon 1.30.28 2006-09-01 * Merged fix for restorecon // handling from Erich Schubert. * Merged translations update and fixfiles fix from Dan Walsh. 1.30.27 2006-08-24 * Merged fix for restorecon symlink handling from Erich Schubert. 1.30.26 2006-08-11 * Merged semanage local file contexts patch from Chris PeBenito. 1.30.25 2006-08-03 * Merged patch from Dan Walsh with: * audit2allow: process MAC_POLICY_LOAD events * newrole: run shell with - prefix to start a login shell * po: po file updates * restorecond: bail if SELinux not enabled * fixfiles: omit -q * genhomedircon: fix exit code if non-root * semodule_deps: install man page 1.30.24 2006-08-03 * Merged secon Makefile fix from Joshua Brindle. 1.30.23 2006-08-03 * Merged netfilter contexts support patch from Chris PeBenito. 1.30.22 2006-07-28 * Merged restorecond size_t fix from Joshua Brindle. 1.30.21 2006-07-28 * Merged secon keycreate patch from Michael LeMay. 1.30.20 2006-07-26 * Merged restorecond fixes from Dan Walsh. Merged updated po files from Dan Walsh. 1.30.19 2006-07-26 * Merged python gettext patch from Stephen Bennett. 1.30.18 2006-07-25 * Merged semodule_deps from Karl MacMillan. 1.30.17 2006-06-29 * Lindent. 1.30.16 2006-06-26 * Merged patch from Dan Walsh with: * -p option (progress) for setfiles and restorecon. * disable context translation for setfiles and restorecon. * on/off values for setsebool. 1.30.15 2006-06-26 * Merged setfiles and semodule_link fixes from Joshua Brindle. 1.30.14 2006-06-16 * Merged fix for setsebool error path from Serge Hallyn. 1.30.13 2006-06-16 * Merged patch from Dan Walsh with: * Updated po files. * Fixes for genhomedircon and seobject. * Audit message for mass relabel by setfiles. 1.30.12 2006-06-02 * Updated fixfiles script for new setfiles location in /sbin. 1.30.11 2006-05-26 * Merged more translations from Dan Walsh. * Merged patch to relocate setfiles to /sbin for early relabel when /usr might not be mounted from Dan Walsh. * Merged semanage/seobject patch to preserve fcontext ordering in list. * Merged secon patch from James Antill. 1.30.10 2006-05-22 * Merged patch with updates to audit2allow, secon, genhomedircon, and semanage from Dan Walsh. 1.30.9 2006-05-08 * Fixed audit2allow and po Makefiles for DESTDIR= builds. * Merged .po file patch from Dan Walsh. * Merged bug fix for genhomedircon. 1.30.8 2006-05-08 * Merged patch from Dan Walsh. This includes audit2allow changes for analysis plugins, internationalization support for several additional programs and added po files, some fixes for semanage, and several cleanups. It also adds a new secon utility. 1.30.7 2006-05-05 * Merged fix warnings patch from Karl MacMillan. 1.30.6 2006-04-14 * Merged semanage prefix support from Russell Coker. 1.30.5 2006-04-11 * Added a test to setfiles to check that the spec file is a regular file. 1.30.4 2006-03-29 * Merged audit2allow fixes for refpolicy from Dan Walsh. * Merged fixfiles patch from Dan Walsh. * Merged restorecond daemon from Dan Walsh. 1.30.3 2006-03-29 * Merged semanage non-MLS fixes from Chris PeBenito. 1.30.2 2006-03-29 * Merged semanage and semodule man page examples from Thomas Bleher. 1.30.1 2006-03-20 * Merged semanage labeling prefix patch from Ivan Gyurdiev. 1.30 2006-03-14 * Updated version for release. 1.29.28 2006-03-13 * Merged German translations (de.po) by Debian translation team from Manoj Srivastava. 1.29.27 2006-03-08 * Merged audit2allow -R support, chcat fix, semanage MLS checks and semanage audit calls from Dan Walsh. 1.29.26 2006-02-15 * Merged semanage bug fix patch from Ivan Gyurdiev. 1.29.25 2006-02-14 * Merged improve bindings patch from Ivan Gyurdiev. 1.29.24 2006-02-14 * Merged semanage usage patch from Ivan Gyurdiev. * Merged use PyList patch from Ivan Gyurdiev. 1.29.23 2006-02-13 * Merged newrole -V/--version support from Glauber de Oliveira Costa. 1.29.22 2006-02-13 * Merged genhomedircon prefix patch from Dan Walsh. 1.29.21 2006-02-13 * Merged optionals in base patch from Joshua Brindle. 1.29.20 2006-02-07 * Merged seuser/user_extra support patch to semodule_package from Joshua Brindle. 1.29.19 2006-02-06 * Merged getopt type fix for semodule_link/expand and sestatus from Chris PeBenito. 1.29.18 2006-02-02 * Merged clone record on set_con patch from Ivan Gyurdiev. 1.29.17 2006-01-30 * Merged genhomedircon fix from Dan Walsh. 1.29.16 2006-01-30 * Merged seusers.system patch from Ivan Gyurdiev. * Merged improve port/fcontext API patch from Ivan Gyurdiev. * Merged genhomedircon patch from Dan Walsh. 1.29.15 2006-01-27 * Merged newrole audit patch from Steve Grubb. 1.29.14 2006-01-27 * Merged seuser -> seuser local rename patch from Ivan Gyurdiev. 1.29.13 2006-01-27 * Merged semanage and semodule access check patches from Joshua Brindle. 1.29.12 2006-01-26 * Merged restorecon, chcat, and semanage patches from Dan Walsh. 1.29.11 2006-01-25 * Modified newrole and run_init to use the loginuid when supported to obtain the Linux user identity to re-authenticate, and to fall back to real uid. Dropped the use of the SELinux user identity, as Linux users are now mapped to SELinux users via seusers and the SELinux user identity space is separate. 1.29.10 2006-01-20 * Merged semanage bug fixes from Ivan Gyurdiev. * Merged semanage fixes from Russell Coker. * Merged chcat.8 and genhomedircon patches from Dan Walsh. 1.29.9 2006-01-19 * Merged chcat, semanage, and setsebool patches from Dan Walsh. 1.29.8 2006-01-18 * Merged semanage fixes from Ivan Gyurdiev. * Merged semanage fixes from Russell Coker. * Merged chcat, genhomedircon, and semanage diffs from Dan Walsh. 1.29.7 2006-01-13 * Merged newrole cleanup patch from Steve Grubb. * Merged setfiles/restorecon performance patch from Russell Coker. * Merged genhomedircon and semanage patches from Dan Walsh. 1.29.6 2006-01-12 * Merged remove add_local/set_local patch from Ivan Gyurdiev. 1.29.5 2006-01-05 * Added filename to semodule error reporting. 1.29.4 2006-01-05 * Merged genhomedircon and semanage patch from Dan Walsh. * Changed semodule error reporting to include argv[0]. 1.29.3 2006-01-04 * Merged semanage getpwnam bug fix from Serge Hallyn (IBM). * Merged patch series from Ivan Gyurdiev. This includes patches to: - cleanup setsebool - update setsebool to apply active booleans through libsemanage - update semodule to use the new semanage_set_rebuild() interface - fix various bugs in semanage * Merged patch from Dan Walsh (Red Hat). This includes fixes for restorecon, chcat, fixfiles, genhomedircon, and semanage. 1.29.2 2005-12-14 * Merged patch for chcat script from Dan Walsh. 1.29.1 2005-12-08 * Merged fix for audit2allow long option list from Dan Walsh. * Merged -r option for restorecon (alias for -R) from Dan Walsh. * Merged chcat script and man page from Dan Walsh. 1.28 2005-12-07 * Updated version for release. 1.27.37 2005-12-07 * Clarified the genhomedircon warning message. 1.27.36 2005-12-05 * Changed genhomedircon to warn on use of ROLE in homedir_template if using managed policy, as libsemanage does not yet support it. 1.27.35 2005-12-02 * Merged genhomedircon bug fix from Dan Walsh. 1.27.34 2005-12-02 * Revised semodule* man pages to refer to checkmodule and to include example sections. 1.27.33 2005-12-01 * Merged audit2allow --tefile and --fcfile support from Dan Walsh. * Merged genhomedircon fix from Dan Walsh. * Merged semodule* man pages from Dan Walsh, and edited them. 1.27.32 2005-12-01 * Changed setfiles to set the MATCHPATHCON_VALIDATE flag to retain validation/canonicalization of contexts during init. 1.27.31 2005-11-29 * Changed genhomedircon to always use user_r for the role in the managed case since user_get_defrole is broken. 1.27.30 2005-11-29 * Merged sestatus, audit2allow, and semanage patch from Dan Walsh. * Fixed semodule -v option. 1.27.29 2005-11-28 * Merged audit2allow python script from Dan Walsh. (old script moved to audit2allow.perl, will be removed later). * Merged genhomedircon fixes from Dan Walsh. * Merged semodule quieting patch from Dan Walsh (inverts default, use -v to restore original behavior). 1.27.28 2005-11-15 * Merged genhomedircon rewrite from Dan Walsh. 1.27.27 2005-11-09 * Merged setsebool cleanup patch from Ivan Gyurdiev. 1.27.26 2005-11-09 * Added -B (--build) option to semodule to force a rebuild. 1.27.25 2005-11-08 * Reverted setsebool patch to call semanage_set_reload_bools(). * Changed setsebool to disable policy reload and to call security_set_boolean_list to update the runtime booleans. 1.27.24 2005-11-08 * Changed setfiles -c to use new flag to set_matchpathcon_flags() to disable context translation by matchpathcon_init(). 1.27.23 2005-11-07 * Changed setfiles for the context canonicalization support. 1.27.22 2005-11-07 * Changed setsebool to call semanage_is_managed() interface and fall back to security_set_boolean_list() if policy is not managed. 1.27.21 2005-11-07 * Merged setsebool memory leak fix from Ivan Gyurdiev. * Merged setsebool patch to call semanage_set_reload_bools() interface from Ivan Gyurdiev. 1.27.20 2005-11-04 * Merged setsebool patch from Ivan Gyurdiev. This moves setsebool from libselinux/utils to policycoreutils, and rewrites it to use libsemanage for permanent boolean changes. 1.27.19 2005-10-25 * Merged semodule support for reload, noreload, and store options from Joshua Brindle. * Merged semodule_package rewrite from Joshua Brindle. 1.27.18 2005-10-20 * Cleaned up usage and error messages and releasing of memory by semodule_* utilities. 1.27.17 2005-10-20 * Corrected error reporting by semodule. 1.27.16 2005-10-19 * Updated semodule_expand for change to sepol interface. 1.27.15 2005-10-19 * Merged fixes for make DESTDIR= builds from Joshua Brindle. 1.27.14 2005-10-18 * Updated semodule_package for sepol interface changes. 1.27.13 2005-10-17 * Updated semodule_expand/link for sepol interface changes. 1.27.12 2005-10-14 * Merged non-PAM Makefile support for newrole and run_init from Timothy Wood. 1.27.11 2005-10-13 * Updated semodule_expand to use get interfaces for hidden sepol_module_package type. 1.27.10 2005-10-13 * Merged newrole and run_init pam config patches from Dan Walsh (Red Hat). 1.27.9 2005-10-13 * Merged fixfiles patch from Dan Walsh (Red Hat). 1.27.8 2005-10-13 * Updated semodule for removal of semanage_strerror. 1.27.7 2005-10-11 * Updated semodule_link and semodule_expand to use shared libsepol. Fixed audit2why to call policydb_init prior to policydb_read (still uses the static libsepol). 1.27.6 2005-10-07 * Updated for changes to libsepol. Changed semodule and semodule_package to use the shared libsepol. Disabled build of semodule_link and semodule_expand for now. Updated audit2why for relocated policydb internal headers, still needs to be converted to a shared lib interface. 1.27.5 2005-10-06 * Fixed warnings in load_policy. 1.27.4 2005-10-06 * Rewrote load_policy to use the new selinux_mkload_policy() interface provided by libselinux. 1.27.3 2005-09-28 * Merged patch to update semodule to the new libsemanage API and improve the user interface from Karl MacMillan (Tresys). * Modified semodule for the create/connect API split. 1.27.2 2005-09-20 * Merged run_init open_init_pty bug fix from Manoj Srivastava (unblock SIGCHLD). Bug reported by Erich Schubert. 1.27.1 2005-09-20 * Merged error shadowing bug fix for restorecon from Dan Walsh. * Merged setfiles usage/man page update for -r option from Dan Walsh. * Merged fixfiles -C patch to ignore :s0 addition on update to a MCS/MLS policy from Dan Walsh. 1.26 2005-09-06 * Updated version for release. 1.25.9 2005-08-31 * Changed setfiles -c to translate the context to raw format prior to calling libsepol. 1.25.8 2005-08-31 * Changed semodule to report errors even without -v, to detect extraneous arguments, and corrected usage message. 1.25.7 2005-08-25 * Merged patch for fixfiles -C from Dan Walsh. 1.25.6 2005-08-22 * Merged fixes for semodule_link and sestatus from Serge Hallyn (IBM). Bugs found by Coverity. 1.25.5 2005-08-02 * Merged patch to move module read/write code from libsemanage to libsepol from Jason Tang (Tresys). 1.25.4 2005-07-27 * Changed semodule* to link with libsemanage. 1.25.3 2005-07-26 * Merged restorecon patch from Ivan Gyurdiev. 1.25.2 2005-07-11 * Merged load_policy, newrole, and genhomedircon patches from Red Hat. 1.25.1 2005-07-06 * Merged loadable module support from Tresys Technology. 1.24 2005-06-20 * Updated version for release. 1.23.11 2005-05-19 * Merged fixfiles and newrole patch from Dan Walsh. * Merged audit2why man page from Dan Walsh. 1.23.10 2005-05-16 * Extended audit2why to incorporate booleans and local user settings when analyzing audit messages. 1.23.9 2005-05-13 * Updated audit2why for sepol_ prefixes on Flask types to avoid namespace collision with libselinux, and to include now. 1.23.8 2005-05-13 * Added audit2why utility. 1.23.7 2005-04-29 * Merged patch for fixfiles from Dan Walsh. Allow passing -F to force reset of customizable contexts. 1.23.6 2005-04-13 * Fixed signed/unsigned pointer bug in load_policy. * Reverted context validation patch for genhomedircon. 1.23.5 2005-04-12 * Reverted load_policy is_selinux_enabled patch from Dan Walsh. Otherwise, an initial policy load cannot be performed using load_policy, e.g. for anaconda. 1.23.4 2005-04-08 * Merged load_policy is_selinux_enabled patch from Dan Walsh. * Merged restorecon verbose output patch from Dan Walsh. * Merged setfiles altroot patch from Chris PeBenito. 1.23.3 2005-03-17 * Merged context validation patch for genhomedircon from Eric Paris. 1.23.2 2005-03-16 * Changed setfiles -c to call set_matchpathcon_flags(3) to turn off processing of .homedirs and .local. 1.23.1 2005-03-14 * Merged rewrite of genhomedircon by Eric Paris. * Changed fixfiles to relabel jfs since it now supports security xattrs (as of 2.6.11). Removed reiserfs until 2.6.12 is released with fixed support for reiserfs and selinux. 1.22 2005-03-09 * Updated version for release. 1.21.22 2005-03-07 * Merged restorecon and genhomedircon patch from Dan Walsh. 1.21.21 2005-02-28 * Merged load_policy and genhomedircon patch from Dan Walsh. 1.21.20 2005-02-24 * Merged fixfiles and genhomedircon patch from Dan Walsh. 1.21.19 2005-02-22 * Merged several fixes from Ulrich Drepper. 1.21.18 2005-02-18 * Changed load_policy to fall back to the original policy upon an error from sepol_genusers(). 1.21.17 2005-02-17 * Merged new genhomedircon script from Dan Walsh. 1.21.16 2005-02-17 * Changed load_policy to call sepol_genusers(). 1.21.15 2005-02-09 * Changed relabel Makefile target to use restorecon. 1.21.14 2005-02-08 * Merged restorecon patch from Dan Walsh. 1.21.13 2005-02-07 * Merged sestatus patch from Dan Walsh. * Merged further change to fixfiles -C from Dan Walsh. 1.21.12 2005-02-02 * Merged further patches for restorecon/setfiles -e and fixfiles -C. 1.21.11 2005-02-02 * Merged patch for fixfiles -C option from Dan Walsh. * Merged patch -e support for restorecon from Dan Walsh. * Merged updated -e support for setfiles from Dan Walsh. 1.21.10 2005-01-31 * Merged patch for open_init_pty from Manoj Srivastava. 1.21.9 2005-01-28 * Merged updated fixfiles script from Dan Walsh. * Merged updated man page for fixfiles from Dan Walsh and re-added unzipped. * Reverted fixfiles patch for file_contexts.local; obsoleted by setfiles rewrite. * Merged error handling patch for restorecon from Dan Walsh. * Merged semi raw mode for open_init_pty helper from Manoj Srivastava. 1.21.8 2005-01-28 * Rewrote setfiles to use matchpathcon and the new interfaces exported by libselinux (>= 1.21.5). 1.21.7 2005-01-27 * Prevent overflow of spec array in setfiles. 1.21.6 2005-01-27 * Merged genhomedircon STARTING_UID bug fix from Dan Walsh. 1.21.5 2005-01-26 * Merged newrole -l support from Darrel Goeddel (TCS). 1.21.4 2005-01-25 * Merged fixfiles patch for file_contexts.local from Dan Walsh. 1.21.3 2005-01-21 * Fixed restorecon to not treat errors from is_context_customizable() as a customizable context. * Merged setfiles/restorecon patch to not reset user field unless -F option is specified from Dan Walsh. 1.21.2 2005-01-21 * Merged open_init_pty helper for run_init from Manoj Srivastava. * Merged audit2allow and genhomedircon man pages from Manoj Srivastava. 1.21.1 2005-01-19 * Merged customizable contexts patch for restorecon/setfiles from Dan Walsh. 1.20 2005-01-06 * Merged fixfiles rewrite from Dan Walsh. * Merged restorecon patch from Dan Walsh. * Merged fixfiles and restorecon patches from Dan Walsh. * Changed restorecon to ignore ENOENT errors from matchpathcon. * Merged nonls patch from Chris PeBenito. * Removed fixfiles.cron. * Merged run_init.8 patch from Dan Walsh. 1.18 2004-11-01 * Merged audit2allow patch from Thomas Bleher, with mods by Dan Walsh. * Merged sestatus patch from Steve Grubb. * Merged fixfiles patch from Dan Walsh. * Added -l option to setfiles to log changes via syslog. * Merged -e option to setfiles to exclude directories. * Merged -R option to restorecon for recursive descent. * Merged sestatus patch from Steve Grubb via Dan Walsh. * Merged load_policy and fixfiles.cron patches from Dan Walsh. * Merged fix for setfiles context validation patch from Colin Walters. * Merged setfiles context validation patch from Colin Walters. * Merged genhomedircon patch from Russell Coker. * Merged restorecon patch from Russell Coker. 1.16 2004-08-13 * Merged audit2allow fix from Tom London. * Merged load_policy man page from Dan Walsh. * Merged newrole bug fix from Chad Hanson. * Changed load_policy to preserve booleans by default. * Changed load_policy to invoke sepol_genbools() instead. * Changed load_policy to also invoke security_load_booleans(). * Merged genhomedircon fixes from Dan Walsh. * Changed restorecon to use realpath. * Merged fixfiles patch from Dan Walsh. * Merged genhomedircon patch from Russell Coker and Dan Walsh. * Merged fixfiles patch and fixfiles.cron script from Dan Walsh. * Merged stat fix for setfiles -s from Russell Coker. 1.14 2004-06-25 * Merged fix for fixfiles. * Merged enhancements to setfiles, fixfiles and restorecon from Dan Walsh. * Merged updated genhomedircon script from Russell Coker. * Merged run_init patch to find initrc_context from Dan Walsh. * Merged fixfiles patch for /etc/selinux from Dan Walsh. * Merged restorecon patch from Dan Walsh. * Merged fixfiles patch from Dan Walsh. 1.12 2004-05-10 * Merged newrole patch from Colin Walters. * Merged fixfiles from Dan Walsh. 1.10 2004-04-05 * Changed setfiles to not abort upon lsetfilecon failures. * Merged sestatus from Chris PeBenito. * Merged fixes for restorecon. * Merged setfiles verbosity patch from Dan Walsh and Stephen Tweedie. * Merged restorecon patch from Dan Walsh. * Revert add_assoc change from setfiles. * Moved restorecon to /sbin. * Disable add_assoc in setfiles by default, use -a to enable. * Merged genhomedircon patch from Dan Walsh. * Merged restorecon patch from Dan Walsh. * Merged setfiles buffer size change from Dan Walsh. * Merged genhomedircon fix from Karl MacMillan of Tresys. This generates separate lines for each prefix. 1.8 2004-03-09 * Merged genhomedircon patch from Karl MacMillan of Tresys. * Removed checkcon script (obsoleted by restorecon -nv). * Replaced restorecon script with C program from Dan Walsh. Uses the new matchpathcon function from libselinux. 1.6 2004-02-18 * Fixed setfiles sorting problem reported by Colin Walters. * Merged setfiles patch from Robert Bihlmeyer, amended by Russell Coker. * Added scripts (checkcon, restorecon, genhomedircon) from Dan Walsh. * Quiet warning about duplicate same specifications if -q is used. * Fixed usage message of audit2allow. 1.4 2003-12-01 * Merged patch from Russell Coker. * Added audit2allow (formerly newrules.pl from policy). * Dropped -lattr from Makefiles. * Merged setfiles check type first patch by Russell Coker. 1.2 2003-09-30 * Merged run_init close file patch from Chris PeBenito. * Merged setfiles stem compression patch by Russell Coker. * Merged setfiles usage/getopt/err patch by Russell Coker. * Merged setfiles altroot patch by Hardened Gentoo team. * Merged i18n patch by Dan Walsh. * Changed Makefiles to allow non-root rpm builds. 1.1 2003-08-13 * Dropped obsolete psid code from setfiles. 1.0 2003-07-11 * Initial public release. policycoreutils-2.3/Makefile000066400000000000000000000007401233221606300162460ustar00rootroot00000000000000SUBDIRS = sepolicy setfiles semanage load_policy newrole run_init sandbox secon audit2allow sestatus semodule_package semodule semodule_link semodule_expand semodule_deps sepolgen-ifgen setsebool scripts po man gui INOTIFYH = $(shell ls /usr/include/sys/inotify.h 2>/dev/null) ifeq (${INOTIFYH}, /usr/include/sys/inotify.h) SUBDIRS += restorecond endif all install relabel clean indent: @for subdir in $(SUBDIRS); do \ (cd $$subdir && $(MAKE) $@) || exit 1; \ done test: policycoreutils-2.3/VERSION000066400000000000000000000000041233221606300156470ustar00rootroot000000000000002.3 policycoreutils-2.3/audit2allow/000077500000000000000000000000001233221606300170345ustar00rootroot00000000000000policycoreutils-2.3/audit2allow/Makefile000066400000000000000000000011411233221606300204710ustar00rootroot00000000000000# Installation directories. PREFIX ?= $(DESTDIR)/usr BINDIR ?= $(PREFIX)/bin LIBDIR ?= $(PREFIX)/lib MANDIR ?= $(PREFIX)/share/man LOCALEDIR ?= /usr/share/locale PYTHON ?= /usr/bin/python all: audit2why audit2why: ln -sf audit2allow audit2why test: all @$(PYTHON) test_audit2allow.py -v install: all -mkdir -p $(BINDIR) install -m 755 audit2allow $(BINDIR) (cd $(BINDIR); ln -sf audit2allow audit2why) install -m 755 sepolgen-ifgen $(BINDIR) -mkdir -p $(MANDIR)/man1 install -m 644 audit2allow.1 $(MANDIR)/man1/ install -m 644 audit2why.1 $(MANDIR)/man1/ clean: rm -f *~ indent: ; relabel: ; policycoreutils-2.3/audit2allow/audit2allow000066400000000000000000000345241233221606300212160ustar00rootroot00000000000000#! /usr/bin/python -Es # Authors: Karl MacMillan # Authors: Dan Walsh # # Copyright (C) 2006-2013 Red Hat # see file 'COPYING' for use and warranty information # # 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 only # # 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 # import sys, os import sepolgen.audit as audit import sepolgen.policygen as policygen import sepolgen.interfaces as interfaces import sepolgen.output as output import sepolgen.objectmodel as objectmodel import sepolgen.defaults as defaults import sepolgen.module as module from sepolgen.sepolgeni18n import _ import selinux.audit2why as audit2why import locale locale.setlocale(locale.LC_ALL, '') class AuditToPolicy: VERSION = "%prog .1" SYSLOG = "/var/log/messages" def __init__(self): self.__options = None self.__parser = None self.__avs = None def __parse_options(self): from optparse import OptionParser parser = OptionParser(version=self.VERSION) parser.add_option("-b", "--boot", action="store_true", dest="boot", default=False, help="audit messages since last boot conflicts with -i") parser.add_option("-a", "--all", action="store_true", dest="audit", default=False, help="read input from audit log - conflicts with -i") parser.add_option("-p", "--policy", dest="policy", default=None, help="Policy file to use for analysis") parser.add_option("-d", "--dmesg", action="store_true", dest="dmesg", default=False, help="read input from dmesg - conflicts with --all and --input") parser.add_option("-i", "--input", dest="input", help="read input from - conflicts with -a") parser.add_option("-l", "--lastreload", action="store_true", dest="lastreload", default=False, help="read input only after the last reload") parser.add_option("-r", "--requires", action="store_true", dest="requires", default=False, help="generate require statements for rules") parser.add_option("-m", "--module", dest="module", help="set the module name - implies --requires") parser.add_option("-M", "--module-package", dest="module_package", help="generate a module package - conflicts with -o and -m") parser.add_option("-o", "--output", dest="output", help="append output to , conflicts with -M") parser.add_option("-D", "--dontaudit", action="store_true", dest="dontaudit", default=False, help="generate policy with dontaudit rules") parser.add_option("-R", "--reference", action="store_true", dest="refpolicy", default=True, help="generate refpolicy style output") parser.add_option("-N", "--noreference", action="store_false", dest="refpolicy", default=False, help="do not generate refpolicy style output") parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="explain generated output") parser.add_option("-e", "--explain", action="store_true", dest="explain_long", default=False, help="fully explain generated output") parser.add_option("-t", "--type", help="only process messages with a type that matches this regex", dest="type") parser.add_option("--perm-map", dest="perm_map", help="file name of perm map") parser.add_option("--interface-info", dest="interface_info", help="file name of interface information") parser.add_option("--debug", dest="debug", action="store_true", default=False, help="leave generated modules for -M") parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=(os.path.basename(sys.argv[0])=="audit2why"), help="Translates SELinux audit messages into a description of why the access was denied") options, args = parser.parse_args() # Make -d, -a, and -i conflict if options.audit is True or options.boot: if options.input is not None: sys.stderr.write("error: --all/--boot conflicts with --input\n") if options.dmesg is True: sys.stderr.write("error: --all/--boot conflicts with --dmesg\n") if options.input is not None and options.dmesg is True: sys.stderr.write("error: --input conflicts with --dmesg\n") # Turn on requires generation if a module name is given. Also verify # the module name. if options.module: name = options.module else: name = options.module_package if name: options.requires = True if not module.is_valid_name(name): sys.stderr.write('error: module names must begin with a letter, optionally followed by letters, numbers, "-", "_", "."\n') sys.exit(2) # Make -M and -o conflict if options.module_package: if options.output: sys.stderr.write("error: --module-package conflicts with --output\n") sys.exit(2) if options.module: sys.stderr.write("error: --module-package conflicts with --module\n") sys.exit(2) self.__options = options def __read_input(self): parser = audit.AuditParser(last_load_only=self.__options.lastreload) filename = None messages = None f = None # Figure out what input we want if self.__options.input is not None: filename = self.__options.input elif self.__options.dmesg: messages = audit.get_dmesg_msgs() elif self.__options.audit: try: messages = audit.get_audit_msgs() except OSError, e: sys.stderr.write('could not run ausearch - "%s"\n' % str(e)) sys.exit(1) elif self.__options.boot: try: messages = audit.get_audit_boot_msgs() except OSError, e: sys.stderr.write('could not run ausearch - "%s"\n' % str(e)) sys.exit(1) else: # This is the default if no input is specified f = sys.stdin # Get the input if filename is not None: try: f = open(filename) except IOError, e: sys.stderr.write('could not open file %s - "%s"\n' % (filename, str(e))) sys.exit(1) if f is not None: parser.parse_file(f) f.close() if messages is not None: parser.parse_string(messages) self.__parser = parser def __process_input(self): if self.__options.type: avcfilter = audit.AVCTypeFilter(self.__options.type) self.__avs = self.__parser.to_access(avcfilter) csfilter = audit.ComputeSidTypeFilter(self.__options.type) self.__role_types = self.__parser.to_role(csfilter) else: self.__avs = self.__parser.to_access() self.__role_types = self.__parser.to_role() def __load_interface_info(self): # Load interface info file if self.__options.interface_info: fn = self.__options.interface_info else: fn = defaults.interface_info() try: fd = open(fn) except: sys.stderr.write("could not open interface info [%s]\n" % fn) sys.exit(1) ifs = interfaces.InterfaceSet() ifs.from_file(fd) fd.close() # Also load perm maps if self.__options.perm_map: fn = self.__options.perm_map else: fn = defaults.perm_map() try: fd = open(fn) except: sys.stderr.write("could not open perm map [%s]\n" % fn) sys.exit(1) perm_maps = objectmodel.PermMappings() perm_maps.from_file(fd) return (ifs, perm_maps) def __output_modulepackage(self, writer, generator): generator.set_module_name(self.__options.module_package) filename = self.__options.module_package + ".te" packagename = self.__options.module_package + ".pp" try: fd = open(filename, "w") except IOError, e: sys.stderr.write("could not write output file: %s\n" % str(e)) sys.exit(1) writer.write(generator.get_module(), fd) fd.close() mc = module.ModuleCompiler() try: mc.create_module_package(filename, self.__options.refpolicy) except RuntimeError, e: print e sys.exit(1) sys.stdout.write(_("******************** IMPORTANT ***********************\n")) sys.stdout.write((_("To make this policy package active, execute:" +\ "\n\nsemodule -i %s\n\n") % packagename)) def __output_audit2why(self): import selinux import seobject for i in self.__parser.avc_msgs: rc = i.type data = i.data if rc >= 0: print "%s\n\tWas caused by:" % i.message if rc == audit2why.ALLOW: print "\t\tUnknown - would be allowed by active policy\n", print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n" print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n" continue if rc == audit2why.DONTAUDIT: print "\t\tUnknown - should be dontaudit'd by active policy\n", print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n" print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n" continue if rc == audit2why.BOOLEAN: if len(data) > 1: print "\tOne of the following booleans was set incorrectly." for b in data: print "\tDescription:\n\t%s\n" % seobject.boolean_desc(b[0]) print "\tAllow access by executing:\n\t# setsebool -P %s %d" % (b[0], b[1]) else: print "\tThe boolean %s was set incorrectly. " % (data[0][0]) print "\tDescription:\n\t%s\n" % seobject.boolean_desc(data[0][0]) print "\tAllow access by executing:\n\t# setsebool -P %s %d" % (data[0][0], data[0][1]) continue if rc == audit2why.TERULE: print "\t\tMissing type enforcement (TE) allow rule.\n" print "\t\tYou can use audit2allow to generate a loadable module to allow this access.\n" continue if rc == audit2why.CONSTRAINT: print #!!!! This avc is a constraint violation. You would need to modify the attributes of either the source or target types to allow this access.\n" print "#Constraint rule:" print "\n\t" + data[0] for reason in data[1:]: print "#\tPossible cause is the source %s and target %s are different.\n" % reason if rc == audit2why.RBAC: print "\t\tMissing role allow rule.\n" print "\t\tAdd an allow rule for the role pair.\n" continue audit2why.finish() return def __output(self): if self.__options.audit2why: try: return self.__output_audit2why() except RuntimeError, e: print e sys.exit(1) g = policygen.PolicyGenerator() g.set_gen_dontaudit(self.__options.dontaudit) if self.__options.module: g.set_module_name(self.__options.module) # Interface generation if self.__options.refpolicy: ifs, perm_maps = self.__load_interface_info() g.set_gen_refpol(ifs, perm_maps) # Explanation if self.__options.verbose: g.set_gen_explain(policygen.SHORT_EXPLANATION) if self.__options.explain_long: g.set_gen_explain(policygen.LONG_EXPLANATION) # Requires if self.__options.requires: g.set_gen_requires(True) # Generate the policy g.add_access(self.__avs) g.add_role_types(self.__role_types) # Output writer = output.ModuleWriter() # Module package if self.__options.module_package: self.__output_modulepackage(writer, g) else: # File or stdout if self.__options.module: g.set_module_name(self.__options.module) if self.__options.output: fd = open(self.__options.output, "a") else: fd = sys.stdout writer.write(g.get_module(), fd) def main(self): try: self.__parse_options() if self.__options.policy: audit2why.init(self.__options.policy) else: audit2why.init() self.__read_input() self.__process_input() self.__output() except KeyboardInterrupt: sys.exit(0) except ValueError, e: print e sys.exit(1) except IOError, e: print e sys.exit(1) if __name__ == "__main__": app = AuditToPolicy() app.main() policycoreutils-2.3/audit2allow/audit2allow.1000066400000000000000000000156301233221606300213520ustar00rootroot00000000000000.\" Hey, Emacs! This is an -*- nroff -*- source file. .\" Copyright (c) 2005 Manoj Srivastava .\" Copyright (c) 2010 Dan Walsh .\" .\" This is free documentation; 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. .\" .\" The GNU General Public License's references to "object code" .\" and "executables" are to be interpreted as the output of any .\" document formatting or typesetting system, including .\" intermediate and printed output. .\" .\" This manual 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 manual; if not, write to the Free .\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, .\" USA. .\" .\" .TH AUDIT2ALLOW "1" "October 2010" "Security Enhanced Linux" NSA .SH NAME .BR audit2allow \- generate SELinux policy allow/dontaudit rules from logs of denied operations .BR audit2why \- translates SELinux audit messages into a description of why the access was denied (audit2allow \-w) .SH SYNOPSIS .B audit2allow .RI [ options "] " .SH OPTIONS .TP .B "\-a" | "\-\-all" Read input from audit and message log, conflicts with \-i .TP .B "\-b" | "\-\-boot" Read input from audit messages since last boot conflicts with \-i .TP .B "\-d" | "\-\-dmesg" Read input from output of .I /bin/dmesg. Note that all audit messages are not available via dmesg when auditd is running; use "ausearch \-m avc | audit2allow" or "\-a" instead. .TP .B "\-D" | "\-\-dontaudit" Generate dontaudit rules (Default: allow) .TP .B "\-h" | "\-\-help" Print a short usage message .TP .B "\-i " | "\-\-input " read input from .I .TP .B "\-l" | "\-\-lastreload" read input only after last policy reload .TP .B "\-m " | "\-\-module " Generate module/require output .TP .B "\-M " Generate loadable module package, conflicts with \-o .TP .B "\-p " | "\-\-policy " Policy file to use for analysis .TP .B "\-o " | "\-\-output " append output to .I .TP .B "\-r" | "\-\-requires" Generate require output syntax for loadable modules. .TP .B "\-N" | "\-\-noreference" Do not generate reference policy, traditional style allow rules. This is the default behavior. .TP .B "\-R" | "\-\-reference" Generate reference policy using installed macros. This attempts to match denials against interfaces and may be inaccurate. .TP .B "\-w" | "\-\-why" Translates SELinux audit messages into a description of why the access was denied .TP .B "\-v" | "\-\-verbose" Turn on verbose output .SH DESCRIPTION .PP This utility scans the logs for messages logged when the system denied permission for operations, and generates a snippet of policy rules which, if loaded into policy, might have allowed those operations to succeed. However, this utility only generates Type Enforcement (TE) allow rules. Certain permission denials may require other kinds of policy changes, e.g. adding an attribute to a type declaration to satisfy an existing constraint, adding a role allow rule, or modifying a constraint. The .BR audit2why (8) utility may be used to diagnose the reason when it is unclear. .PP Care must be exercised while acting on the output of this utility to ensure that the operations being permitted do not pose a security threat. Often it is better to define new domains and/or types, or make other structural changes to narrowly allow an optimal set of operations to succeed, as opposed to blindly implementing the sometimes broad changes recommended by this utility. Certain permission denials are not fatal to the application, in which case it may be preferable to simply suppress logging of the denial via a 'dontaudit' rule rather than an 'allow' rule. .PP .SH EXAMPLE .nf .B NOTE: These examples are for systems using the audit package. If you do .B not use the audit package, the AVC messages will be in /var/log/messages. .B Please substitute /var/log/messages for /var/log/audit/audit.log in the .B examples. .PP .B Using audit2allow to generate module policy $ cat /var/log/audit/audit.log | audit2allow \-m local > local.te $ cat local.te module local 1.0; require { class file { getattr open read }; type myapp_t; type etc_t; }; allow myapp_t etc_t:file { getattr open read }; .B Using audit2allow to generate module policy using reference policy $ cat /var/log/audit/audit.log | audit2allow \-R \-m local > local.te $ cat local.te policy_module(local, 1.0) gen_require(` type myapp_t; type etc_t; }; files_read_etc_files(myapp_t) .B Building module policy using Makefile # SELinux provides a policy devel environment under # /usr/share/selinux/devel including all of the shipped # interface files. # You can create a te file and compile it by executing $ make \-f /usr/share/selinux/devel/Makefile local.pp # This make command will compile a local.te file in the current # directory. If you did not specify a "pp" file, the make file # will compile all "te" files in the current directory. After # you compile your te file into a "pp" file, you need to install # it using the semodule command. $ semodule \-i local.pp .B Building module policy manually # Compile the module $ checkmodule \-M \-m \-o local.mod local.te # Create the package $ semodule_package \-o local.pp \-m local.mod # Load the module into the kernel $ semodule \-i local.pp .B Using audit2allow to generate and build module policy $ cat /var/log/audit/audit.log | audit2allow \-M local Generating type enforcement file: local.te Compiling policy: checkmodule \-M \-m \-o local.mod local.te Building package: semodule_package \-o local.pp \-m local.mod ******************** IMPORTANT *********************** In order to load this newly created policy package into the kernel, you are required to execute semodule \-i local.pp .B Using audit2allow to generate monolithic (non\-module) policy $ cd /etc/selinux/$SELINUXTYPE/src/policy $ cat /var/log/audit/audit.log | audit2allow >> domains/misc/local.te $ cat domains/misc/local.te allow cupsd_config_t unconfined_t:fifo_file { getattr ioctl }; $ make load .fi .PP .SH AUTHOR This manual page was written by .I Manoj Srivastava , for the Debian GNU/Linux system. It was updated by Dan Walsh .PP The .B audit2allow utility has contributions from several people, including .I Justin R. Smith and .I Yuichi Nakamura. and .I Dan Walsh policycoreutils-2.3/audit2allow/audit2why000066400000000000000000000344601233221606300207060ustar00rootroot00000000000000#! /usr/bin/python -Es # Authors: Karl MacMillan # Authors: Dan Walsh # # Copyright (C) 2006-2013 Red Hat # see file 'COPYING' for use and warranty information # # 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 only # # 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 # import sys, os import sepolgen.audit as audit import sepolgen.policygen as policygen import sepolgen.interfaces as interfaces import sepolgen.output as output import sepolgen.objectmodel as objectmodel import sepolgen.defaults as defaults import sepolgen.module as module from sepolgen.sepolgeni18n import _ import selinux.audit2why as audit2why import locale locale.setlocale(locale.LC_ALL, '') class AuditToPolicy: VERSION = "%prog .1" SYSLOG = "/var/log/messages" def __init__(self): self.__options = None self.__parser = None self.__avs = None def __parse_options(self): from optparse import OptionParser parser = OptionParser(version=self.VERSION) parser.add_option("-b", "--boot", action="store_true", dest="boot", default=False, help="audit messages since last boot conflicts with -i") parser.add_option("-a", "--all", action="store_true", dest="audit", default=False, help="read input from audit log - conflicts with -i") parser.add_option("-p", "--policy", dest="policy", default=None, help="Policy file to use for analysis") parser.add_option("-d", "--dmesg", action="store_true", dest="dmesg", default=False, help="read input from dmesg - conflicts with --all and --input") parser.add_option("-i", "--input", dest="input", help="read input from - conflicts with -a") parser.add_option("-l", "--lastreload", action="store_true", dest="lastreload", default=False, help="read input only after the last reload") parser.add_option("-r", "--requires", action="store_true", dest="requires", default=False, help="generate require statements for rules") parser.add_option("-m", "--module", dest="module", help="set the module name - implies --requires") parser.add_option("-M", "--module-package", dest="module_package", help="generate a module package - conflicts with -o and -m") parser.add_option("-o", "--output", dest="output", help="append output to , conflicts with -M") parser.add_option("-D", "--dontaudit", action="store_true", dest="dontaudit", default=False, help="generate policy with dontaudit rules") parser.add_option("-R", "--reference", action="store_true", dest="refpolicy", default=True, help="generate refpolicy style output") parser.add_option("-N", "--noreference", action="store_false", dest="refpolicy", default=False, help="do not generate refpolicy style output") parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="explain generated output") parser.add_option("-e", "--explain", action="store_true", dest="explain_long", default=False, help="fully explain generated output") parser.add_option("-t", "--type", help="only process messages with a type that matches this regex", dest="type") parser.add_option("--perm-map", dest="perm_map", help="file name of perm map") parser.add_option("--interface-info", dest="interface_info", help="file name of interface information") parser.add_option("--debug", dest="debug", action="store_true", default=False, help="leave generated modules for -M") parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=(os.path.basename(sys.argv[0])=="audit2why"), help="Translates SELinux audit messages into a description of why the access was denied") options, args = parser.parse_args() # Make -d, -a, and -i conflict if options.audit is True or options.boot: if options.input is not None: sys.stderr.write("error: --all/--boot conflicts with --input\n") if options.dmesg is True: sys.stderr.write("error: --all/--boot conflicts with --dmesg\n") if options.input is not None and options.dmesg is True: sys.stderr.write("error: --input conflicts with --dmesg\n") # Turn on requires generation if a module name is given. Also verify # the module name. if options.module: name = options.module else: name = options.module_package if name: options.requires = True if not module.is_valid_name(name): sys.stderr.write('error: module names must begin with a letter, optionally followed by letters, numbers, "-", "_", "."\n') sys.exit(2) # Make -M and -o conflict if options.module_package: if options.output: sys.stderr.write("error: --module-package conflicts with --output\n") sys.exit(2) if options.module: sys.stderr.write("error: --module-package conflicts with --module\n") sys.exit(2) self.__options = options def __read_input(self): parser = audit.AuditParser(last_load_only=self.__options.lastreload) filename = None messages = None f = None # Figure out what input we want if self.__options.input is not None: filename = self.__options.input elif self.__options.dmesg: messages = audit.get_dmesg_msgs() elif self.__options.audit: try: messages = audit.get_audit_msgs() except OSError, e: sys.stderr.write('could not run ausearch - "%s"\n' % str(e)) sys.exit(1) elif self.__options.boot: try: messages = audit.get_audit_boot_msgs() except OSError, e: sys.stderr.write('could not run ausearch - "%s"\n' % str(e)) sys.exit(1) else: # This is the default if no input is specified f = sys.stdin # Get the input if filename is not None: try: f = open(filename) except IOError, e: sys.stderr.write('could not open file %s - "%s"\n' % (filename, str(e))) sys.exit(1) if f is not None: parser.parse_file(f) f.close() if messages is not None: parser.parse_string(messages) self.__parser = parser def __process_input(self): if self.__options.type: avcfilter = audit.AVCTypeFilter(self.__options.type) self.__avs = self.__parser.to_access(avcfilter) csfilter = audit.ComputeSidTypeFilter(self.__options.type) self.__role_types = self.__parser.to_role(csfilter) else: self.__avs = self.__parser.to_access() self.__role_types = self.__parser.to_role() def __load_interface_info(self): # Load interface info file if self.__options.interface_info: fn = self.__options.interface_info else: fn = defaults.interface_info() try: fd = open(fn) except: sys.stderr.write("could not open interface info [%s]\n" % fn) sys.exit(1) ifs = interfaces.InterfaceSet() ifs.from_file(fd) fd.close() # Also load perm maps if self.__options.perm_map: fn = self.__options.perm_map else: fn = defaults.perm_map() try: fd = open(fn) except: sys.stderr.write("could not open perm map [%s]\n" % fn) sys.exit(1) perm_maps = objectmodel.PermMappings() perm_maps.from_file(fd) return (ifs, perm_maps) def __output_modulepackage(self, writer, generator): generator.set_module_name(self.__options.module_package) filename = self.__options.module_package + ".te" packagename = self.__options.module_package + ".pp" try: fd = open(filename, "w") except IOError, e: sys.stderr.write("could not write output file: %s\n" % str(e)) sys.exit(1) writer.write(generator.get_module(), fd) fd.close() mc = module.ModuleCompiler() try: mc.create_module_package(filename, self.__options.refpolicy) except RuntimeError, e: print e sys.exit(1) sys.stdout.write(_("******************** IMPORTANT ***********************\n")) sys.stdout.write((_("To make this policy package active, execute:" +\ "\n\nsemodule -i %s\n\n") % packagename)) def __output_audit2why(self): import selinux import seobject for i in self.__parser.avc_msgs: rc = i.type data = i.data if rc >= 0: print "%s\n\tWas caused by:" % i.message if rc == audit2why.ALLOW: print "\t\tUnknown - would be allowed by active policy\n", print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n" print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n" continue if rc == audit2why.DONTAUDIT: print "\t\tUnknown - should be dontaudit'd by active policy\n", print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n" print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n" continue if rc == audit2why.BOOLEAN: if len(data) > 1: print "\tOne of the following booleans was set incorrectly." for b in data: print "\tDescription:\n\t%s\n" % seobject.boolean_desc(b[0]) print "\tAllow access by executing:\n\t# setsebool -P %s %d" % (b[0], b[1]) else: print "\tThe boolean %s was set incorrectly. " % (data[0][0]) print "\tDescription:\n\t%s\n" % seobject.boolean_desc(data[0][0]) print "\tAllow access by executing:\n\t# setsebool -P %s %d" % (data[0][0], data[0][1]) continue if rc == audit2why.TERULE: print "\t\tMissing type enforcement (TE) allow rule.\n" print "\t\tYou can use audit2allow to generate a loadable module to allow this access.\n" continue if rc == audit2why.CONSTRAINT: print #!!!! This avc is a constraint violation. You would need to modify the attributes of either the source or target types to allow this access.\n" print "#Constraint rule: \n\t" + data[0] for reason in data[1:]: print "#\tPossible cause is the source %s and target %s are different.\n\b" % reason if rc == audit2why.RBAC: print "\t\tMissing role allow rule.\n" print "\t\tAdd an allow rule for the role pair.\n" continue audit2why.finish() return def __output(self): if self.__options.audit2why: try: return self.__output_audit2why() except RuntimeError, e: print e sys.exit(1) g = policygen.PolicyGenerator() g.set_gen_dontaudit(self.__options.dontaudit) if self.__options.module: g.set_module_name(self.__options.module) # Interface generation if self.__options.refpolicy: ifs, perm_maps = self.__load_interface_info() g.set_gen_refpol(ifs, perm_maps) # Explanation if self.__options.verbose: g.set_gen_explain(policygen.SHORT_EXPLANATION) if self.__options.explain_long: g.set_gen_explain(policygen.LONG_EXPLANATION) # Requires if self.__options.requires: g.set_gen_requires(True) # Generate the policy g.add_access(self.__avs) g.add_role_types(self.__role_types) # Output writer = output.ModuleWriter() # Module package if self.__options.module_package: self.__output_modulepackage(writer, g) else: # File or stdout if self.__options.module: g.set_module_name(self.__options.module) if self.__options.output: fd = open(self.__options.output, "a") else: fd = sys.stdout writer.write(g.get_module(), fd) def main(self): try: self.__parse_options() if self.__options.policy: audit2why.init(self.__options.policy) else: audit2why.init() self.__read_input() self.__process_input() self.__output() except KeyboardInterrupt: sys.exit(0) except ValueError, e: print e sys.exit(1) except IOError, e: print e sys.exit(1) if __name__ == "__main__": app = AuditToPolicy() app.main() policycoreutils-2.3/audit2allow/audit2why.1000066400000000000000000000000271233221606300210350ustar00rootroot00000000000000.so man1/audit2allow.1 policycoreutils-2.3/audit2allow/sepolgen-ifgen000066400000000000000000000110451233221606300216620ustar00rootroot00000000000000#! /usr/bin/python -Es # # Authors: Karl MacMillan # # Copyright (C) 2006 Red Hat # see file 'COPYING' for use and warranty information # # 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 only # # 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 # # Parse interfaces and output extracted information about them # suitable for policy generation. By default writes the output # to the default location (obtained from sepolgen.defaults), but # will output to another file provided as an argument: # sepolgen-ifgen [headers] [output-filename] import sys import os import tempfile import subprocess import selinux import sepolgen.refparser as refparser import sepolgen.defaults as defaults import sepolgen.interfaces as interfaces VERSION = "%prog .1" ATTR_HELPER = "/usr/bin/sepolgen-ifgen-attr-helper" def parse_options(): from optparse import OptionParser parser = OptionParser(version=VERSION) parser.add_option("-o", "--output", dest="output", default=defaults.interface_info(), help="filename to store output") parser.add_option("-i", "--interfaces", dest="headers", default=defaults.headers(), help="location of the interface header files") parser.add_option("-a", "--attribute_info", dest="attribute_info") parser.add_option("-p", "--policy", dest="policy_path") parser.add_option("-v", "--verbose", action="store_true", default=False, help="print debuging output") parser.add_option("-d", "--debug", action="store_true", default=False, help="extra debugging output") parser.add_option("--no_attrs", action="store_true", default=False, help="do not retrieve attribute access from kernel policy") options, args = parser.parse_args() return options def get_policy(): p = selinux.selinux_current_policy_path() if p and os.path.exists(p): return p i = selinux.security_policyvers() p = selinux.selinux_binary_policy_path() + "." + str(i) while i > 0 and not os.path.exists(p): i = i - 1 p = selinux.selinux_binary_policy_path() + "." + str(i) if i > 0: return p return None def get_attrs(policy_path): try: if not policy_path: policy_path = get_policy() if not policy_path: sys.stderr.write("No installed policy to check\n") return None outfile = tempfile.NamedTemporaryFile() except IOError, e: sys.stderr.write("could not open attribute output file\n") return None except OSError: # SELinux Disabled Machine return None fd = open("/dev/null","w") ret = subprocess.Popen([ATTR_HELPER, policy_path, outfile.name], stdout=fd).wait() fd.close() if ret != 0: sys.stderr.write("could not run attribute helper") return None attrs = interfaces.AttributeSet() try: attrs.from_file(outfile) except: print "error parsing attribute info" return None return attrs def main(): options = parse_options() # Open the output first to generate errors before parsing try: f = open(options.output, "w") except IOError, e: sys.stderr.write("could not open output file [%s]\n" % options.output) return 1 if options.verbose: log = sys.stdout else: log = None # Get the attibutes from the binary attrs = None if not options.no_attrs: attrs = get_attrs(options.policy_path) if attrs is None: return 1 # Parse the headers try: headers = refparser.parse_headers(options.headers, output=log, debug=options.debug) except ValueError, e: print "error parsing headers" print str(e) return 1 if_set = interfaces.InterfaceSet(output=log) if_set.add_headers(headers, attributes=attrs) if_set.to_file(f) f.close() if refparser.success: return 0 else: return 1 if __name__ == "__main__": sys.exit(main()) policycoreutils-2.3/audit2allow/test.log000066400000000000000000000232341233221606300205220ustar00rootroot00000000000000node=bill.example.com type=AVC_PATH msg=audit(1166045975.667:1128): path="/usr/lib/libGL.so.1.2" type=AVC msg=audit(1166045975.667:1129): avc: denied { write } for comm=local dev=dm-0 name=root.lock pid=10581 scontext=system_u:system_r:postfix_local_t:s0 tclass=file tcontext=system_u:object_r:mail_spool_t:s0 node=bob.example.com type=PATH msg=audit(1166111074.191:74): item=0 name="/etc/auto.net" inode=16483485 dev=fd:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:automount_lock_t:s0 type=CWD msg=audit(1166111074.191:74): cwd="/" node=bob.example.com type=SYSCALL msg=audit(1166111074.191:74): arch=40000003 syscall=33 success=no exit=-13 a0=92c5288 a1=1 a2=154d50 a3=92c5120 items=1 ppid=13935 pid=13944 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="automount" exe="/usr/sbin/automount" subj=system_u:system_r:automount_t:s0 key=(null) node=bob.example.com type=AVC msg=audit(1166111074.191:74): avc: denied { execute } for pid=13944 comm="automount" name="auto.net" dev=dm-0 ino=16483485 scontext=system_u:system_r:automount_t:s0 tcontext=system_u:object_r:automount_lock_t:s0 tclass=file node=james.example.com type=SYSCALL msg=audit(1165963069.244:851): arch=40000003 syscall=102 success=no exit=-13 a0=2 a1=bf96a830 a2=b5b1e8 a3=9e58ac0 items=0 ppid=21133 pid=21134 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts10 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) node=james.example.com type=AVC msg=audit(1165963069.244:851): avc: denied { name_bind } for pid=21134 comm="httpd" src=81 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket node=tom.example.com type=SYSCALL msg=audit(1165963069.244:852): arch=40000003 syscall=102 success=no exit=-13 a0=2 a1=bf96a830 a2=b5b1e8 a3=9e58ac0 items=0 ppid=21133 pid=21134 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts10 comm="smbd" exe="/usr/sbin/smbd" subj=system_u:system_r:smbd_t:s0 key=(null) node=tom.example.com type=AVC msg=audit(1165963069.244:852): avc: denied { name_connect } for pid=21134 comm="smbd" src=81 scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket node=mary.example.com type=SYSCALL msg=audit(1166023021.373:910): arch=40000003 syscall=12 success=no exit=-13 a0=8493cd8 a1=cc3 a2=3282ec a3=bf992a04 items=0 ppid=24423 pid=24427 auid=3267 uid=0 gid=0 euid=3267 suid=3267 fsuid=3267 egid=3267 sgid=3267 fsgid=3267 tty=(none) comm="vsftpd" exe="/usr/sbin/vsftpd" subj=system_u:system_r:ftpd_t:s0 key=(null) node=mary.example.com type=AVC msg=audit(1166023021.373:910): avc: denied { search } for pid=24427 comm="vsftpd" name="home" dev=dm-0 ino=9338881 scontext=system_u:system_r:ftpd_t:s0 tcontext=system_u:object_r:home_root_t:s0 tclass=dir node=tom.example.com type=SYSCALL msg=audit(1165963069.244:852): arch=40000003 syscall=102 success=no exit=-13 a0=2 a1=bf96a830 a2=b5b1e8 a3=9e58ac0 items=0 ppid=21133 pid=21134 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts10 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) node=tom.example.com type=AVC msg=audit(1165963069.244:852): avc: denied { name_connect } for pid=21134 comm="httpd" src=81 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket node=dan.example.com type=AVC_PATH msg=audit(1166017682.366:877): path="/var/www/html/index.html" node=dan.example.com type=SYSCALL msg=audit(1166017682.366:877): arch=40000003 syscall=196 success=no exit=-13 a0=96226a8 a1=bf88b01c a2=31fff4 a3=2008171 items=0 ppid=23762 pid=23768 auid=3267 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) node=dan.example.com type=AVC msg=audit(1166017682.366:877): avc: denied { execute_no_trans } for pid=23768 comm="httpd" name="index.html" dev=dm-0 ino=7996439 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:var_t:s0 tclass=file node=judy.example.com type=SYSCALL msg=audit(1165963069.244:853): arch=40000003 syscall=102 success=no exit=-13 a0=2 a1=bf96a830 a2=b5b1e8 a3=9e58ac0 items=0 ppid=21133 pid=21134 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts10 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) node=judy.example.com type=AVC msg=audit(1165963069.244:853): avc: denied { name_connect } for pid=21134 comm="httpd" src=81 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:mysqld_port_t:s0 tclass=tcp_socket node=judy.example.com type=SYSCALL msg=audit(1165963069.244:853): arch=40000003 syscall=102 success=no exit=-13 a0=2 a1=bf96a830 a2=b5b1e8 a3=9e58ac0 items=0 ppid=21133 pid=21134 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts10 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) node=judy.example.com type=AVC msg=audit(1165963069.244:853): avc: denied { name_connect } for pid=21134 comm="httpd" src=81 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket node=patty.example.com type=AVC_PATH msg=audit(1166036885.378:1097): path="/var/www/cgi-bin" node=patty.example.com type=SYSCALL msg=audit(1166036885.378:1097): arch=40000003 syscall=196 success=no exit=-13 a0=9624f38 a1=bf88b11c a2=31fff4 a3=2008171 items=0 ppid=23762 pid=23770 auid=3267 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) node=patty.example.com type=AVC msg=audit(1166036885.378:1097): avc: denied { execute } for pid=23770 comm="httpd" name="cgi-bin" dev=dm-0 ino=7995597 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_script_exec_t:s0 tclass=file node=sam.example.com type=SYSCALL msg=audit(1166038880.318:1103): arch=40000003 syscall=5 success=no exit=-13 a0=bf96f068 a1=18800 a2=0 a3=bf973110 items=0 ppid=23765 pid=12387 auid=3267 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) comm="sealert.cgi" exe="/usr/bin/perl" subj=system_u:system_r:httpd_sys_script_t:s0 key=(null) node=sam.example.com type=AVC msg=audit(1166038880.318:1103): avc: denied { write } for pid=12387 comm="sealert.cgi" name="sealert-upload" dev=dm-0 ino=8093724 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=file node=holycross.devel.redhat.com type=AVC_PATH msg=audit(1166027294.395:952): path="/home/devel/dwalsh/public_html" node=holycross.devel.redhat.com type=SYSCALL msg=audit(1166027294.395:952): arch=40000003 syscall=196 success=yes exit=0 a0=8495230 a1=849c830 a2=874ff4 a3=328d28 items=0 ppid=7234 pid=7236 auid=3267 uid=3267 gid=3267 euid=3267 suid=3267 fsuid=3267 egid=3267 sgid=3267 fsgid=3267 tty=(none) comm="vsftpd" exe="/usr/sbin/vsftpd" subj=system_u:system_r:ftpd_t:s0 key=(null) node=holycross.devel.redhat.com type=AVC msg=audit(1166027294.395:952): avc: denied { getattr } for pid=7236 comm="vsftpd" name="public_html" dev=dm-0 ino=9601649 scontext=system_u:system_r:ftpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=file host=dhcppc2 type=AVC msg=audit(1216729188.853:241): avc: denied { read } for pid=14066 comm="qemu-kvm" name="HelpdeskRHEL4-RHEL4.x86_64" dev=tmpfs ino=333 scontext=system_u:system_r:qemu_t:s0 tcontext=system_u:object_r:fixed_disk_device_t:s0 tclass=blk_file host=dhcppc2 type=SYSCALL msg=audit(1216729188.853:241): arch=c000003e syscall=2 success=no exit=-13 a0=7fff6f654680 a1=0 a2=1a4 a3=3342f67a70 items=0 ppid=2953 pid=14066 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="qemu-kvm" exe="/usr/bin/qemu-kvm" subj=system_u:system_r:qemu_t:s0 key=(null) node=mallorn.farre.nom type=AVC msg=audit(1228276291.360:466): avc: denied { execute } for pid=13015 comm="npviewer.bin" path="/opt/real/RealPlayer/mozilla/nphelix.so" dev=dm-0 ino=2850912 scontext=unconfined_u:unconfined_r:nsplugin_t:s0 tcontext=unconfined_u:object_r:usr_t:s0 tclass=file node=mallorn.farre.nom type=SYSCALL msg=audit(1228276291.360:466): arch=40000003 syscall=192 success=no exit=-13 a0=0 a1=9eec a2=5 a3=802 items=0 ppid=13014 pid=13015 auid=500 uid=500 gid=500 euid=500 suid=500 fsuid=500 egid=500 sgid=500 fsgid=500 tty=(none) ses=63 comm="npviewer.bin" exe="/usr/lib/nspluginwrapper/npviewer.bin" subj=unconfined_u:unconfined_r:nsplugin_t:s0 key=(null) node=mary.example.com type=SYSCALL msg=audit(1166023021.373:910): arch=40000003 syscall=12 success=no exit=-13 a0=8493cd8 a1=cc3 a2=3282ec a3=bf992a04 items=0 ppid=24423 pid=24427 auid=3267 uid=0 gid=0 euid=3267 suid=3267 fsuid=3267 egid=3267 sgid=3267 fsgid=3267 tty=(none) comm="vssmbd" exe="/usr/sbin/vssmbd" subj=system_u:system_r:smbd_t:s0 key=(null) node=mary.example.com type=AVC msg=audit(1166023021.373:910): avc: denied { read } for pid=24427 comm="vssmbd" name="home" dev=dm-0 ino=9338881 scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:object_r:ssh_home_t:s0 tclass=file node=lilly.example.com type=AVC_PATH msg=audit(1164783469.561:109): path="/linuxtest/LVT/lvt/log.current" node=lilly.example.com type=SYSCALL msg=audit(1164783469.561:109): arch=14 syscall=11 success=yes exit=0 a0=10120520 a1=10120a78 a2=10120970 a3=118 items=0 ppid=8310 pid=8311 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="smbd" exe="/usr/sbin/smbd" subj=root:system_r:smbd_t:s0 key=(null) node=lilly.example.com type=AVC msg=audit(1164783469.561:109): avc: denied { append } for pid=8311 comm="smbd" name="log.current" dev=dm-0 ino=130930 scontext=root:system_r:smbd_t:s0 tcontext=root:object_r:default_t:s0 tclass=dir policycoreutils-2.3/audit2allow/test_audit2allow.py000066400000000000000000000030551233221606300226770ustar00rootroot00000000000000import unittest, os, shutil from tempfile import mkdtemp from subprocess import Popen, PIPE class Audit2allowTests(unittest.TestCase): def assertDenied(self, err): self.assert_('Permission denied' in err, '"Permission denied" not found in %r' % err) def assertNotFound(self, err): self.assert_('not found' in err, '"not found" not found in %r' % err) def assertFailure(self, status): self.assert_(status != 0, '"Succeeded when it should have failed') def assertSuccess(self, cmd, status, err): self.assert_(status == 0, '"%s should have succeeded for this test %r' % (cmd, err)) def test_sepolgen_ifgen(self): "Verify sepolgen-ifgen works" p = Popen(['sudo', 'sepolgen-ifgen'], stdout = PIPE) out, err = p.communicate() if err: print(out, err) self.assertSuccess("sepolgen-ifgen", p.returncode, err) def test_audit2allow(self): "Verify audit2allow works" p = Popen(['audit2allow',"-i","test.log"], stdout = PIPE) out, err = p.communicate() if err: print(out, err) self.assertSuccess("audit2allow", p.returncode, err) def test_audit2why(self): "Verify audit2why works" p = Popen(['audit2why',"-i","test.log"], stdout = PIPE) out, err = p.communicate() if err: print(out, err) self.assertSuccess("audit2why", p.returncode, err) if __name__ == "__main__": unittest.main() policycoreutils-2.3/gui/000077500000000000000000000000001233221606300153715ustar00rootroot00000000000000policycoreutils-2.3/gui/Makefile000066400000000000000000000026111233221606300170310ustar00rootroot00000000000000# Installation directories. PREFIX ?= ${DESTDIR}/usr SYSCONFDIR ?= ${DESTDIR}/etc BINDIR ?= $(PREFIX)/bin SHAREDIR ?= $(PREFIX)/share/system-config-selinux DATADIR ?= $(PREFIX)/share MANDIR ?= $(PREFIX)/share/man TARGETS= \ booleansPage.py \ domainsPage.py \ fcontextPage.py \ html_util.py \ loginsPage.py \ mappingsPage.py \ modulesPage.py \ polgen.glade \ portsPage.py \ semanagePage.py \ statusPage.py \ system-config-selinux.glade \ system-config-selinux.png \ usersPage.py all: $(TARGETS) system-config-selinux.py polgengui.py install: all -mkdir -p $(MANDIR)/man8 -mkdir -p $(SHAREDIR) -mkdir -p $(BINDIR) -mkdir -p $(DATADIR)/pixmaps -mkdir -p $(DATADIR)/icons/hicolor/24x24/apps -mkdir -p $(SYSCONFDIR) -mkdir -p $(DATADIR)/polkit-1/actions/ install -m 755 system-config-selinux.py $(SHAREDIR) install -m 755 system-config-selinux $(BINDIR) install -m 755 polgengui.py $(SHAREDIR) install -m 644 $(TARGETS) $(SHAREDIR) install -m 644 system-config-selinux.8 $(MANDIR)/man8 install -m 644 selinux-polgengui.8 $(MANDIR)/man8 install -m 644 system-config-selinux.png $(DATADIR)/pixmaps install -m 644 system-config-selinux.png $(DATADIR)/icons/hicolor/24x24/apps install -m 644 system-config-selinux.png $(DATADIR)/system-config-selinux install -m 644 *.desktop $(DATADIR)/system-config-selinux install -m 644 org.selinux.config.policy $(DATADIR)/polkit-1/actions/ clean: indent: relabel: policycoreutils-2.3/gui/booleansPage.py000066400000000000000000000173721233221606300203540ustar00rootroot00000000000000# # booleansPage.py - GUI for Booleans page in system-config-securitylevel # # Dan Walsh # # Copyright 2006, 2007 Red Hat, Inc. # # 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 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import string import gtk import gtk.glade import os import gobject import sys import tempfile import seobject import semanagePage INSTALLPATH='/usr/share/system-config-selinux' sys.path.append(INSTALLPATH) import commands ENFORCING=0 PERMISSIVE=1 DISABLED=2 ## ## I18N ## PROGNAME="policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=False, codeset = 'utf-8') except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode from glob import fnmatch class Modifier: def __init__(self,name, on, save): self.on=on self.name=name self.save=save def set(self,value): self.on=value self.save=True def isOn(self): return self.on class Boolean(Modifier): def __init__(self,name, val, save=False): Modifier.__init__(self,name, val, save) ACTIVE = 0 MODULE = 1 DESC = 2 BOOLEAN = 3 class booleansPage: def __init__(self, xml, doDebug=None): self.xml = xml self.window = self.xml.get_widget("mainWindow").get_root_window() self.local = False self.types=[] self.selinuxsupport = True self.typechanged = False self.doDebug = doDebug self.busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH) self.ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) # Bring in widgets from glade file. self.typeHBox = xml.get_widget("typeHBox") self.booleanSW = xml.get_widget("booleanSW") self.booleansFilter = xml.get_widget("booleansFilter") self.booleansFilter.connect("focus_out_event", self.filter_changed) self.booleansFilter.connect("activate", self.filter_changed) self.booleansView = xml.get_widget("booleansView") self.typeLabel = xml.get_widget("typeLabel") self.modifySeparator = xml.get_widget("modifySeparator") self.revertButton = xml.get_widget("booleanRevertButton") self.revertButton.set_sensitive(self.local) self.revertButton.connect("clicked", self.on_revert_clicked) listStore = gtk.ListStore(gobject.TYPE_STRING) cell = gtk.CellRendererText() self.store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) self.store.set_sort_column_id(1, gtk.SORT_ASCENDING) self.booleansView.set_model(self.store) checkbox = gtk.CellRendererToggle() checkbox.connect("toggled", self.boolean_toggled) col = gtk.TreeViewColumn('Active', checkbox, active = ACTIVE) col.set_clickable(True) col.set_sort_column_id(ACTIVE) self.booleansView.append_column(col) col = gtk.TreeViewColumn("Module", gtk.CellRendererText(), text=MODULE) col.set_sort_column_id(MODULE) col.set_resizable(True) self.booleansView.append_column(col) col = gtk.TreeViewColumn("Description", gtk.CellRendererText(), text=DESC) col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) col.set_fixed_width(400) col.set_sort_column_id(DESC) col.set_resizable(True) self.booleansView.append_column(col) col = gtk.TreeViewColumn("Name", gtk.CellRendererText(), text=BOOLEAN) col.set_sort_column_id(BOOLEAN) col.set_resizable(True) self.booleansView.set_search_equal_func(self.__search) self.booleansView.append_column(col) self.filter="" self.load(self.filter) def error(self, message): dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, message) dlg.set_position(gtk.WIN_POS_MOUSE) dlg.show_all() dlg.run() dlg.destroy() def __search(self, model, col, key, i): sort_col = self.store.get_sort_column_id()[0] if sort_col > 0: val = model.get_value(i, sort_col) if val.lower().startswith(key.lower()): return False return True def wait(self): self.window.set_cursor(self.busy_cursor) semanagePage.idle_func() def ready(self): self.window.set_cursor(self.ready_cursor) semanagePage.idle_func() def deleteDialog(self): store, iter = self.booleansView.get_selection().get_selected() if iter == None: return boolean = store.get_value(iter, BOOLEAN) # change cursor if boolean == None: return try: self.wait() (rc, out) = commands.getstatusoutput("semanage boolean -d %s" % boolean) self.ready() if rc != 0: return self.error(out) self.load(self.filter) except ValueError, e: self.error(e.args[0]) def filter_changed(self, *arg): filter = arg[0].get_text() if filter != self.filter: self.load(filter) self.filter=filter def use_menus(self): return False def get_description(self): return _("Boolean") def match(self,key, filter=""): try: f=filter.lower() cat=self.booleans.get_category(key).lower() val=self.booleans.get_desc(key).lower() k=key.lower() return val.find(f) >= 0 or k.find(f) >= 0 or cat.find(f) >= 0 except: return False def load(self, filter=None): self.store.clear() self.booleans = seobject.booleanRecords() booleansList = self.booleans.get_all(self.local) for name in booleansList: rec = booleansList[name] if self.match(name, filter): iter=self.store.append() self.store.set_value(iter, ACTIVE, rec[2] == 1) self.store.set_value(iter, MODULE, self.booleans.get_category(name)) self.store.set_value(iter, DESC, self.booleans.get_desc(name)) self.store.set_value(iter, BOOLEAN, name) def boolean_toggled(self, widget, row): iter = self.store.get_iter(row) val = self.store.get_value(iter, ACTIVE) key = self.store.get_value(iter, BOOLEAN) self.store.set_value(iter, ACTIVE , not val) self.wait() setsebool="/usr/sbin/setsebool -P %s %d" % (key, not val) rc,out = commands.getstatusoutput(setsebool) if rc != 0: self.error(out) self.load(self.filter) self.ready() def on_revert_clicked(self, button): self.wait() setsebool="semanage boolean --deleteall" commands.getstatusoutput(setsebool) self.load(self.filter) self.ready() def on_local_clicked(self, button): self.local = not self.local self.revertButton.set_sensitive(self.local) if self.local: button.set_label(_("all")) else: button.set_label(_("Customized")) self.load(self.filter) return True policycoreutils-2.3/gui/domainsPage.py000066400000000000000000000120021233221606300201650ustar00rootroot00000000000000## domainsPage.py - show selinux domains ## Copyright (C) 2009 Red Hat, Inc. ## 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., 675 Mass Ave, Cambridge, MA 02139, USA. ## Author: Dan Walsh import string import gtk import gtk.glade import os import commands import gobject import sys import seobject import selinux from semanagePage import *; from sepolicy import get_all_entrypoint_domains ## ## I18N ## PROGNAME="policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=False, codeset = 'utf-8') except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode class domainsPage(semanagePage): def __init__(self, xml): semanagePage.__init__(self, xml, "domains", _("Process Domain")) self.domain_filter = xml.get_widget("domainsFilterEntry") self.domain_filter.connect("focus_out_event", self.filter_changed) self.domain_filter.connect("activate", self.filter_changed) self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) self.view.set_model(self.store) self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Domain Name"), gtk.CellRendererText(), text = 0) col.set_sort_column_id(0) col.set_resizable(True) self.view.append_column(col) self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Mode"), gtk.CellRendererText(), text = 1) col.set_sort_column_id(1) col.set_resizable(True) self.view.append_column(col) self.view.get_selection().connect("changed", self.itemSelected) self.permissive_button = xml.get_widget("permissiveButton") self.enforcing_button = xml.get_widget("enforcingButton") self.domains=get_all_entrypoint_domains() self.load() def get_modules(self): modules=[] fd=os.popen("semodule -l") mods = fd.readlines() fd.close() for l in mods: modules.append(l.split()[0]) return modules def load(self, filter=""): self.filter=filter self.store.clear() try: modules=self.get_modules() for domain in self.domains: if not self.match(domain, filter): continue iter = self.store.append() self.store.set_value(iter, 0, domain) t = "permissive_%s_t" % domain if t in modules: self.store.set_value(iter, 1, _("Permissive")) else: self.store.set_value(iter, 1, "") except: pass self.view.get_selection().select_path ((0,)) def itemSelected(self, selection): store, iter = selection.get_selected() if iter == None: return p = store.get_value(iter, 1) == _("Permissive") self.permissive_button.set_sensitive(not p) self.enforcing_button.set_sensitive(p) def deleteDialog(self): # Do nothing return self.delete() def delete(self): selection = self.view.get_selection() store, iter = selection.get_selected() domain = store.get_value(iter, 0) try: self.wait() status, output = commands.getstatusoutput("semanage permissive -d %s_t" % domain) self.ready() if status != 0: self.error(output) else: domain = store.set_value(iter, 1, "") self.itemSelected(selection) except ValueError, e: self.error(e.args[0]) def propertiesDialog(self): # Do nothing return def addDialog(self): # Do nothing return self.add() def add(self): selection = self.view.get_selection() store, iter = selection.get_selected() domain = store.get_value(iter, 0) try: self.wait() status, output = commands.getstatusoutput("semanage permissive -a %s_t" % domain) self.ready() if status != 0: self.error(output) else: domain = store.set_value(iter, 1, _("Permissive")) self.itemSelected(selection) except ValueError, e: self.error(e.args[0]) policycoreutils-2.3/gui/fcontextPage.py000066400000000000000000000200021233221606300203640ustar00rootroot00000000000000## fcontextPage.py - show selinux mappings ## Copyright (C) 2006 Red Hat, Inc. ## 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., 675 Mass Ave, Cambridge, MA 02139, USA. ## Author: Dan Walsh import gtk import gtk.glade import os import gobject import seobject import commands from semanagePage import *; SPEC_COL = 0 TYPE_COL = 1 FTYPE_COL = 2 class context: def __init__(self, scontext): self.scontext = scontext con=scontext.split(":") self.type = con[0] if len(con) > 1: self.mls = con[1] else: self.mls = "s0" def __str__(self): return self.scontext ## ## I18N ## PROGNAME="policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=False, codeset = 'utf-8') except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode class fcontextPage(semanagePage): def __init__(self, xml): semanagePage.__init__(self, xml, "fcontext", _("File Labeling")) self.fcontextFilter = xml.get_widget("fcontextFilterEntry") self.fcontextFilter.connect("focus_out_event", self.filter_changed) self.fcontextFilter.connect("activate", self.filter_changed) self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) self.view = xml.get_widget("fcontextView") self.view.set_model(self.store) self.view.set_search_equal_func(self.search) col = gtk.TreeViewColumn(_("File\nSpecification"), gtk.CellRendererText(), text=SPEC_COL) col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) col.set_fixed_width(250) col.set_sort_column_id(SPEC_COL) col.set_resizable(True) self.view.append_column(col) col = gtk.TreeViewColumn(_("Selinux\nFile Type"), gtk.CellRendererText(), text=TYPE_COL) col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) col.set_fixed_width(250) col.set_sort_column_id(TYPE_COL) col.set_resizable(True) self.view.append_column(col) col = gtk.TreeViewColumn(_("File\nType"), gtk.CellRendererText(), text=2) col.set_sort_column_id(FTYPE_COL) col.set_resizable(True) self.view.append_column(col) self.store.set_sort_column_id(SPEC_COL, gtk.SORT_ASCENDING) self.load() self.fcontextEntry = xml.get_widget("fcontextEntry") self.fcontextFileTypeCombo = xml.get_widget("fcontextFileTypeCombo") liststore=self.fcontextFileTypeCombo.get_model() for k in seobject.file_types: if len(k) > 0 and k[0] != '-': iter=liststore.append() liststore.set_value(iter, 0, k) iter = liststore.get_iter_first() self.fcontextFileTypeCombo.set_active_iter(iter) self.fcontextTypeEntry = xml.get_widget("fcontextTypeEntry") self.fcontextMLSEntry = xml.get_widget("fcontextMLSEntry") def match(self, fcon_dict, k, filter): try: f=filter.lower() for con in k: k=con.lower() if k.find(f) >= 0: return True for con in fcon_dict[k]: k=con.lower() if k.find(f) >= 0: return True except: pass return False def load(self, filter=""): self.filter=filter self.fcontext=seobject.fcontextRecords() self.store.clear() fcon_dict=self.fcontext.get_all(self.local) keys = fcon_dict.keys() keys.sort() for k in keys: if not self.match(fcon_dict, k, filter): continue iter=self.store.append() self.store.set_value(iter, SPEC_COL, k[0]) self.store.set_value(iter, FTYPE_COL, k[1]) if fcon_dict[k]: rec="%s:%s" % (fcon_dict[k][2], seobject.translate(fcon_dict[k][3],False)) else: rec="<>" self.store.set_value(iter, TYPE_COL, rec) self.view.get_selection().select_path ((0,)) def filter_changed(self, *arg): filter = arg[0].get_text() if filter != self.filter: self.load(filter) def dialogInit(self): store, iter = self.view.get_selection().get_selected() self.fcontextEntry.set_text(store.get_value(iter, SPEC_COL)) self.fcontextEntry.set_sensitive(False) scontext = store.get_value(iter, TYPE_COL) scon=context(scontext) self.fcontextTypeEntry.set_text(scon.type) self.fcontextMLSEntry.set_text(scon.mls) type=store.get_value(iter, FTYPE_COL) liststore=self.fcontextFileTypeCombo.get_model() iter = liststore.get_iter_first() while iter != None and liststore.get_value(iter,0) != type: iter = liststore.iter_next(iter) if iter != None: self.fcontextFileTypeCombo.set_active_iter(iter) self.fcontextFileTypeCombo.set_sensitive(False) def dialogClear(self): self.fcontextEntry.set_text("") self.fcontextEntry.set_sensitive(True) self.fcontextFileTypeCombo.set_sensitive(True) self.fcontextTypeEntry.set_text("") self.fcontextMLSEntry.set_text("s0") def delete(self): store, iter = self.view.get_selection().get_selected() try: fspec=store.get_value(iter, SPEC_COL) ftype=store.get_value(iter, FTYPE_COL) self.wait() (rc, out) = commands.getstatusoutput("semanage fcontext -d -f '%s' '%s'" % (ftype, fspec)) self.ready() if rc != 0: return self.error(out) store.remove(iter) self.view.get_selection().select_path ((0,)) except ValueError, e: self.error(e.args[0]) def add(self): ftype=["", "--", "-d", "-c", "-b", "-s", "-l", "-p" ] fspec=self.fcontextEntry.get_text().strip() type=self.fcontextTypeEntry.get_text().strip() mls=self.fcontextMLSEntry.get_text().strip() list_model=self.fcontextFileTypeCombo.get_model() active = self.fcontextFileTypeCombo.get_active() self.wait() (rc, out) = commands.getstatusoutput("semanage fcontext -a -t %s -r %s -f '%s' '%s'" % (type, mls, ftype[active], fspec)) self.ready() if rc != 0: self.error(out) return False iter=self.store.append() self.store.set_value(iter, SPEC_COL, fspec) self.store.set_value(iter, FTYPE_COL, ftype) self.store.set_value(iter, TYPE_COL, "%s:%s" % (type, mls)) def modify(self): fspec=self.fcontextEntry.get_text().strip() type=self.fcontextTypeEntry.get_text().strip() mls=self.fcontextMLSEntry.get_text().strip() list_model=self.fcontextFileTypeCombo.get_model() iter = self.fcontextFileTypeCombo.get_active_iter() ftype=list_model.get_value(iter,0) self.wait() (rc, out) = commands.getstatusoutput("semanage fcontext -m -t %s -r %s -f '%s' '%s'" % (type, mls, ftype, fspec)) self.ready() if rc != 0: self.error(out) return False store, iter = self.view.get_selection().get_selected() self.store.set_value(iter, SPEC_COL, fspec) self.store.set_value(iter, FTYPE_COL, ftype) self.store.set_value(iter, TYPE_COL, "%s:%s" % (type, mls)) policycoreutils-2.3/gui/html_util.py000066400000000000000000000117221233221606300177470ustar00rootroot00000000000000# Authors: John Dennis # # Copyright (C) 2007 Red Hat, Inc. # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # __all__ = [ 'escape_html', 'unescape_html', 'html_to_text', 'html_document', ] import htmllib import formatter as Formatter import string from types import * import StringIO #------------------------------------------------------------------------------ class TextWriter(Formatter.DumbWriter): def __init__(self, file=None, maxcol=80, indent_width=4): Formatter.DumbWriter.__init__(self, file, maxcol) self.indent_level = 0 self.indent_width = indent_width self._set_indent() def _set_indent(self): self.indent_col = self.indent_level * self.indent_width self.indent = ' ' * self.indent_col def new_margin(self, margin, level): self.indent_level = level self._set_indent() def send_label_data(self, data): data = data + ' ' if len(data) > self.indent_col: self.send_literal_data(data) else: offset = self.indent_col - len(data) self.send_literal_data(' ' * offset + data) def send_flowing_data(self, data): if not data: return atbreak = self.atbreak or data[0] in string.whitespace col = self.col maxcol = self.maxcol write = self.file.write col = self.col if col == 0: write(self.indent) col = self.indent_col for word in data.split(): if atbreak: if col + len(word) >= maxcol: write('\n' + self.indent) col = self.indent_col else: write(' ') col = col + 1 write(word) col = col + len(word) atbreak = 1 self.col = col self.atbreak = data[-1] in string.whitespace class HTMLParserAnchor(htmllib.HTMLParser): def __init__(self, formatter, verbose=0): htmllib.HTMLParser.__init__(self, formatter, verbose) def anchor_bgn(self, href, name, type): self.anchor = href def anchor_end(self): if self.anchor: self.handle_data(' (%s) ' % self.anchor) self.anchor = None #------------------------------------------------------------------------------ def escape_html(s): if s is None: return None s = s.replace("&", "&") # Must be done first! s = s.replace("<", "<") s = s.replace(">", ">") s = s.replace("'", "'") s = s.replace('"', """) return s def unescape_html(s): if s is None: return None if '&' not in s: return s s = s.replace("<", "<") s = s.replace(">", ">") s = s.replace("'", "'") s = s.replace(""", '"') s = s.replace("&", "&") # Must be last return s def html_to_text(html, maxcol=80): try: buffer = StringIO.StringIO() formatter = Formatter.AbstractFormatter(TextWriter(buffer, maxcol)) parser = HTMLParserAnchor(formatter) parser.feed(html) parser.close() text = buffer.getvalue() buffer.close() return text except Exception, e: log_program.error('cannot convert html to text: %s' % e) return None def html_document(*body_components): '''Wrap the body components in a HTML document structure with a valid header. Accepts a variable number of arguments of of which canb be: * string * a sequences of strings (tuple or list). * a callable object taking no parameters and returning a string or sequence of strings. ''' head = '\n \n \n \n \n' tail = '\n \n' doc = head for body_component in body_components: if type(body_component) is StringTypes: doc += body_component elif type(body_component) in [TupleType, ListType]: for item in body_component: doc += item elif callable(body_component): result = body_component() if type(result) in [TupleType, ListType]: for item in result: doc += item else: doc += result else: doc += body_component doc += tail return doc policycoreutils-2.3/gui/loginsPage.py000066400000000000000000000154011233221606300200340ustar00rootroot00000000000000## loginsPage.py - show selinux mappings ## Copyright (C) 2006 Red Hat, Inc. ## 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., 675 Mass Ave, Cambridge, MA 02139, USA. ## Author: Dan Walsh import string import gtk import gtk.glade import os import gobject import sys import commands import seobject from semanagePage import *; ## ## I18N ## PROGNAME="policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=False, codeset = 'utf-8') except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode class loginsPage(semanagePage): def __init__(self, xml): self.firstTime = False semanagePage.__init__(self, xml, "logins", _("User Mapping")) self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) self.view.set_model(self.store) self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Login\nName"), gtk.CellRendererText(), text = 0) col.set_sort_column_id(0) col.set_resizable(True) self.view.append_column(col) col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text = 1) col.set_resizable(True) self.view.append_column(col) col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text = 2) col.set_resizable(True) self.view.append_column(col) self.load() self.loginsNameEntry = xml.get_widget("loginsNameEntry") self.loginsSelinuxUserCombo = xml.get_widget("loginsSelinuxUserCombo") self.loginsMLSEntry = xml.get_widget("loginsMLSEntry") def load(self, filter = ""): self.filter=filter self.login = seobject.loginRecords() dict = self.login.get_all(0) keys = dict.keys() keys.sort() self.store.clear() for k in keys: range = seobject.translate(dict[k][1]) if not (self.match(k, filter) or self.match(dict[k][0], filter) or self.match(range, filter)): continue iter = self.store.append() self.store.set_value(iter, 0, k) self.store.set_value(iter, 1, dict[k][0]) self.store.set_value(iter, 2, range) self.view.get_selection().select_path ((0,)) def __dialogSetup(self): if self.firstTime == True: return self.firstTime = True liststore = gtk.ListStore(gobject.TYPE_STRING) self.loginsSelinuxUserCombo.set_model(liststore) cell = gtk.CellRendererText() self.loginsSelinuxUserCombo.pack_start(cell, True) self.loginsSelinuxUserCombo.add_attribute(cell, 'text', 0) selusers = seobject.seluserRecords().get_all(0) keys = selusers.keys() keys.sort() for k in keys: if k != "system_u": self.loginsSelinuxUserCombo.append_text(k) iter = liststore.get_iter_first() while liststore.get_value(iter,0) != "user_u": iter = liststore.iter_next(iter) self.loginsSelinuxUserCombo.set_active_iter(iter) def dialogInit(self): self.__dialogSetup() store, iter = self.view.get_selection().get_selected() self.loginsNameEntry.set_text(store.get_value(iter, 0)) self.loginsNameEntry.set_sensitive(False) self.loginsMLSEntry.set_text(store.get_value(iter, 2)) seuser = store.get_value(iter, 1) liststore = self.loginsSelinuxUserCombo.get_model() iter = liststore.get_iter_first() while iter != None and liststore.get_value(iter,0) != seuser: iter = liststore.iter_next(iter) if iter != None: self.loginsSelinuxUserCombo.set_active_iter(iter) def dialogClear(self): self.__dialogSetup() self.loginsNameEntry.set_text("") self.loginsNameEntry.set_sensitive(True) self.loginsMLSEntry.set_text("s0") def delete(self): store, iter = self.view.get_selection().get_selected() try: login=store.get_value(iter, 0) if login == "root" or login == "__default__": raise ValueError(_("Login '%s' is required") % login) self.wait() (rc, out) = commands.getstatusoutput("semanage login -d %s" % login) self.ready() if rc != 0: self.error(out) return False store.remove(iter) self.view.get_selection().select_path ((0,)) except ValueError, e: self.error(e.args[0]) def add(self): target=self.loginsNameEntry.get_text().strip() serange=self.loginsMLSEntry.get_text().strip() if serange == "": serange="s0" list_model=self.loginsSelinuxUserCombo.get_model() iter = self.loginsSelinuxUserCombo.get_active_iter() seuser = list_model.get_value(iter,0) self.wait() (rc, out) = commands.getstatusoutput("semanage login -a -s %s -r %s %s" % (seuser, serange, target)) self.ready() if rc != 0: self.error(out) return False iter = self.store.append() self.store.set_value(iter, 0, target) self.store.set_value(iter, 1, seuser) self.store.set_value(iter, 2, seobject.translate(serange)) def modify(self): target=self.loginsNameEntry.get_text().strip() serange=self.loginsMLSEntry.get_text().strip() if serange == "": serange = "s0" list_model = self.loginsSelinuxUserCombo.get_model() iter = self.loginsSelinuxUserCombo.get_active_iter() seuser=list_model.get_value(iter,0) self.wait() (rc, out) = commands.getstatusoutput("semanage login -m -s %s -r %s %s" % (seuser, serange, target)) self.ready() if rc != 0: self.error(out) return False store, iter = self.view.get_selection().get_selected() self.store.set_value(iter, 0, target) self.store.set_value(iter, 1, seuser) self.store.set_value(iter, 2, seobject.translate(serange)) policycoreutils-2.3/gui/mappingsPage.py000066400000000000000000000034231233221606300203600ustar00rootroot00000000000000## mappingsPage.py - show selinux mappings ## Copyright (C) 2006 Red Hat, Inc. ## 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., 675 Mass Ave, Cambridge, MA 02139, USA. ## Author: Dan Walsh import string import gtk import gtk.glade import os import gobject import sys import seobject ## ## I18N ## PROGNAME="policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=False, codeset = 'utf-8') except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode class loginsPage: def __init__(self, xml): self.xml = xml self.view = xml.get_widget("mappingsView") self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) self.view.set_model(self.store) self.login = loginRecords() dict = self.login.get_all(0) keys = dict.keys() keys.sort() for k in keys: print "%-25s %-25s %-25s" % (k, dict[k][0], translate(dict[k][1])) policycoreutils-2.3/gui/modulesPage.py000066400000000000000000000144371233221606300202210ustar00rootroot00000000000000## modulesPage.py - show selinux mappings ## Copyright (C) 2006-2009 Red Hat, Inc. ## 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., 675 Mass Ave, Cambridge, MA 02139, USA. ## Author: Dan Walsh import string import gtk import gtk.glade import os import commands import gobject import sys import seobject import selinux from semanagePage import *; from subprocess import Popen, PIPE ## ## I18N ## PROGNAME="policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=False, codeset = 'utf-8') except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode class modulesPage(semanagePage): def __init__(self, xml): semanagePage.__init__(self, xml, "modules", _("Policy Module")) self.module_filter = xml.get_widget("modulesFilterEntry") self.module_filter.connect("focus_out_event", self.filter_changed) self.module_filter.connect("activate", self.filter_changed) self.audit_enabled = False self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) self.view.set_model(self.store) self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Module Name"), gtk.CellRendererText(), text = 0) col.set_sort_column_id(0) col.set_resizable(True) self.view.append_column(col) self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Version"), gtk.CellRendererText(), text = 1) self.enable_audit_button = xml.get_widget("enableAuditButton") self.enable_audit_button.connect("clicked", self.enable_audit) self.new_button = xml.get_widget("newModuleButton") self.new_button.connect("clicked", self.new_module) col.set_sort_column_id(1) col.set_resizable(True) self.view.append_column(col) self.store.set_sort_func(1,self.sort_int, "") status, self.policy_type = selinux.selinux_getpolicytype() self.load() def sort_int(self, treemodel, iter1, iter2, user_data): try: p1 = int(treemodel.get_value(iter1,1)) p2 = int(treemodel.get_value(iter1,1)) if p1 > p2: return 1 if p1 == p2: return 0 return -1 except: return 0 def load(self, filter=""): self.filter=filter self.store.clear() try: fd = Popen("semodule -l", shell=True, stdout=PIPE).stdout l = fd.readlines() fd.close() for i in l: module, ver, newline = i.split('\t') if not (self.match(module, filter) or self.match(ver, filter)): continue iter = self.store.append() self.store.set_value(iter, 0, module.strip()) self.store.set_value(iter, 1, ver.strip()) except: pass self.view.get_selection().select_path ((0,)) def new_module(self, args): try: Popen(["/usr/share/system-config-selinux/polgengui.py"]) except ValueError, e: self.error(e.args[0]) def delete(self): store, iter = self.view.get_selection().get_selected() module = store.get_value(iter, 0) try: self.wait() status, output = commands.getstatusoutput("semodule -r %s" % module) self.ready() if status != 0: self.error(output) else: store.remove(iter) self.view.get_selection().select_path ((0,)) except ValueError, e: self.error(e.args[0]) def enable_audit(self, button): self.audit_enabled = not self.audit_enabled try: self.wait() if self.audit_enabled: status, output =commands.getstatusoutput("semodule -DB") button.set_label(_("Disable Audit")) else: status, output =commands.getstatusoutput("semodule -B") button.set_label(_("Enable Audit")) self.ready() if status != 0: self.error(output) except ValueError, e: self.error(e.args[0]) def disable_audit(self, button): try: self.wait() status, output =commands.getstatusoutput("semodule -B") self.ready() if status != 0: self.error(output) except ValueError, e: self.error(e.args[0]) def propertiesDialog(self): # Do nothing return def addDialog(self): dialog = gtk.FileChooserDialog(_("Load Policy Module"), None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) filter = gtk.FileFilter() filter.set_name("Policy Files") filter.add_pattern("*.pp") dialog.add_filter(filter) response = dialog.run() if response == gtk.RESPONSE_OK: self.add(dialog.get_filename()) dialog.destroy() def add(self, file): try: self.wait() status, output =commands.getstatusoutput("semodule -i %s" % file) self.ready() if status != 0: self.error(output) else: self.load() except ValueError, e: self.error(e.args[0]) policycoreutils-2.3/gui/org.selinux.config.policy000066400000000000000000000016401233221606300223340ustar00rootroot00000000000000 System Config SELinux http://fedorahosted.org/system-config-selinux Run System Config SELinux Authentication is required to run system-config-selinux system-selinux no no auth_admin /usr/share/system-config-selinux/system-config-selinux.py true policycoreutils-2.3/gui/polgen.glade000066400000000000000000004257311233221606300176670ustar00rootroot00000000000000 False 5 normal Red Hat 2007 www.redhat.com GPL Daniel Walsh <dwalsh@redhat.com> translator-credits False False False True end 0 False 12 Add Booleans Dialog mouse 400 dialog True False 6 True False end gtk-cancel -6 True True True False True False False 0 gtk-add -5 True True True False True False False 1 False True end 0 True False 2 2 12 6 True False 0 Boolean Name GTK_FILL True False 0 Description 1 2 GTK_FILL True True • False False True True 1 2 True True • False False True True 1 2 1 2 True True 1 False 5 mouse dialog True True True False 24 True False end gtk-cancel -6 True True True False True False False 0 gtk-add -5 True True True True False True False False 1 False True end 0 True False SELinux Policy Generation Tool True False 18 True False left False True False True False 0 <b>Select the policy type for the application or user role you want to confine:</b> True False False 5 0 True False True False True False 12 True False 6 True False 0 <b>Applications</b> True False False 0 True False True False False False 0 True False 6 Standard Init Daemon True True False Standard Init Daemon are daemons started on boot via init scripts. Usually requires a script in /etc/rc.d/init.d True True False False 0 DBUS System Daemon True True False Standard Init Daemon are daemons started on boot via init scripts. Usually requires a script in /etc/rc.d/init.d True True init_radiobutton False False 1 Internet Services Daemon (inetd) True True False Internet Services Daemon are daemons started by xinetd True True init_radiobutton False False 2 Web Application/Script (CGI) True True False Web Applications/Script (CGI) CGI scripts started by the web server (apache) True True init_radiobutton False False 3 User Application True True False User Application are any application that you would like to confine that is started by a user True True init_radiobutton False False 4 Sandbox True True False User Application are any application that you would like to confine that is started by a user True True init_radiobutton False False 5 False False 1 True True 1 False True 0 True False 6 True False 0 <b>Login Users</b> True False False 0 True False True False False False 0 True False 6 Existing User Roles True True False Modify an existing login user record. True True init_radiobutton False False 0 Minimal Terminal User Role True True False This user will login to a machine only via a terminal or remote login. By default this user will have no setuid, no networking, no su, no sudo. True True init_radiobutton False False 1 Minimal X Windows User Role True True False This user can login to a machine via X or terminal. By default this user will have no setuid, no networking, no sudo, no su True True init_radiobutton False False 2 User Role True True False User with full networking, no setuid applications without transition, no sudo, no su. True True init_radiobutton False False 3 Admin User Role True True False User with full networking, no setuid applications without transition, no su, can sudo to Root Administration Roles True True init_radiobutton False False 4 True False 1 True True 1 False True 1 True False 6 True False 0 <b>Root Users</b> True False False 0 True False True False False False 0 True False Root Admin User Role True True False Select Root Administrator User Role, if this user will be used to administer the machine while running as root. This user will not be able to login to the system directly. True True init_radiobutton False False 0 False False 1 True True 1 True True 2 True True 0 True True 0 True True 1 True True False Main Tab False tab True False True False 0 <b>Enter name of application or user role:</b> True False False 5 0 True False 3 3 12 6 True False 0 Name GTK_FILL True True Enter complete path for executable to be confined. • False False True True 1 2 1 2 ... True True False True 2 3 1 2 GTK_FILL True True Enter unique name for the confined application or user role. • False False True True 1 3 True False 0 Executable 1 2 GTK_FILL True False 0 Init script 2 3 GTK_FILL True True Enter complete path to init script used to start the confined application. • False False True True 1 2 2 3 ... True True False True 2 3 2 3 GTK_FILL True True 1 1 True False Name Tab 1 False tab True False True False 0 <b>Select existing role to modify:</b> True False False 5 0 True True automatic automatic in True True Select the user roles that will transiton to the %s domain. False True True 1 2 True False role tab 2 False tab True False True False 0 <b>Select roles that %s will transition to:</b> True False False 5 0 True True True True Select applications domains that %s will transition to. False True True 1 3 True False transition role tab 3 False tab True False True False 0 <b>Select the user_roles that will transition to %s:</b> True False False 5 0 True True True True Select the user roles that will transiton to this applications domains. False True True 1 4 True False User Tab 4 False tab True False True False 0 <b>Select domains that %s will administer:</b> True False False 5 0 True True True True Select the domains that you would like this user administer. False True True 1 5 True False Admin Tab 5 False tab True False True False 0 <b>Select additional roles for %s:</b> True False False 5 0 True True True True Select the domains that you would like this user administer. False True True 1 6 True False Roles Tab 6 False tab True False True False 0 <b>Enter network ports that %s binds on:</b> True False False 5 0 True False 6 True False 0 <b>TCP Ports</b> True False False 0 True False True False False False 0 True False 6 True False 12 All True True False Allows %s to bind to any udp port True True False False 10 0 600-1024 True True False Allow %s to call bindresvport with 0. Binding to port 600-1024 True True False False 10 1 Unreserved Ports (>1024) True True False Enter a comma separated list of udp ports or ranges of ports that %s binds to. Example: 612, 650-660 True True False False 10 2 True True 0 True False 12 True False 0 Select Ports False False 5 0 True True Allows %s to bind to any udp ports > 1024 • False False True True True True 1 True True 1 True True 1 True True 1 True True 1 True False 6 True False 0 <b>UDP Ports</b> True False False 0 True False True False False False 0 True False 6 True False 12 All True True False Allows %s to bind to any udp port True True False False 10 0 600-1024 True True False Allow %s to call bindresvport with 0. Binding to port 600-1024 True True False False 10 1 Unreserved Ports (>1024) True True False Enter a comma separated list of udp ports or ranges of ports that %s binds to. Example: 612, 650-660 True True False False 10 2 True True 0 True False 12 True False 0 Select Ports False False 5 0 True True Allows %s to bind to any udp ports > 1024 • False False True True True True 1 True True 1 True True 1 True True 1 True True 2 7 True False Network Bind tab 7 False tab True False True False 0 <b>Select network ports that %s connects to:</b> True False False 5 0 True False 6 True False 0 <b>TCP Ports</b> True False False 0 True False True False False False 0 True False 12 All True True False Allows %s to connect to any tcp port True True False False 10 0 True False 0 Select Ports False False 5 1 True True Enter a comma separated list of tcp ports or ranges of ports that %s connects to. Example: 612, 650-660 • False False True True True True 2 True True 1 True True 1 True True 1 True False 6 True False 0 <b>UDP Ports</b> True False False 0 True False True False False False 0 True False 12 All True True False Allows %s to connect to any udp port True True False False 10 0 True False 0 Select Ports False False 5 1 True True Enter a comma separated list of udp ports or ranges of ports that %s connects to. Example: 612, 650-660 • False False True True True True 2 True True 1 True True 1 True True 2 8 True False Network Connect Tab 8 False tab True False True False 0 <b>Select common application traits for %s:</b> True False False 5 0 True False 6 Writes syslog messages True True False True True False False 0 Create/Manipulate temporary files in /tmp True True False True True False False 1 Uses Pam for authentication True True False True True False False 2 Uses nsswitch or getpw* calls True True False True True False False 3 Uses dbus True True False True True False False 4 Sends audit messages True True False True True False False 5 Interacts with the terminal True True False True True False False 6 Sends email True True False True True False False 7 True True 1 9 True False Common Tab 9 False tab True False True False 0 <b>Add files/directories that %s manages</b> True False False 5 0 True False 12 True False 6 True True False True False 0 0 True False 2 True False gtk-add False False 0 True False Add File True False False 1 False False 0 True True False True False 0 0 True False 2 True False gtk-add False False 0 True False Add Directory True False False 1 False False 1 gtk-delete True True False True False False 2 False False 4 0 True True automatic automatic in True True Files/Directories which the %s "manages". Pid Files, Log Files, /var/lib Files ... False True True 1 True True 1 10 True False Add Tab 10 False tab True False True False 0 <b>Add booleans from the %s policy:</b> True False False 5 0 True False 12 True False 6 True True False True False 0 0 True False 2 True False gtk-add False False 0 True False Add Boolean True False False 1 False False 0 gtk-delete True True False True False False 1 False True 4 0 True True automatic automatic in True True Add/Remove booleans used by the %s domain True True 1 True True 1 11 True False 11 False tab True False True False 0 <b>Which directory you will generate the %s policy?</b> True False False 0 True False 12 True False Policy Directory False False 5 0 True True • False False True True True True 1 ... True True False True False False 2 False False 12 1 12 True False 12 False tab True True 0 True False end gtk-cancel True True True False True False False 0 gtk-go-back True True True False True False False 1 gtk-go-forward True True True False True False False 2 False False 5 1 policycoreutils-2.3/gui/polgengui.py000066400000000000000000001007601233221606300177400ustar00rootroot00000000000000#!/usr/bin/python -Es # # polgengui.py - GUI for SELinux Config tool in system-config-selinux # # Dan Walsh # # Copyright (C) 2007-2013 Red Hat # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # import signal import string import gtk import gtk.glade import os import gobject import gnome import sys try: from sepolicy import generate except ValueError,e: sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) sys.exit(1) import sepolicy.interface import commands import re def get_all_modules(): try: all_modules = [] rc, output=commands.getstatusoutput("semodule -l 2>/dev/null") if rc == 0: l = output.split("\n") for i in l: all_modules.append(i.split()[0]) except: pass return all_modules ## ## I18N ## PROGNAME="policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=False, codeset = 'utf-8') except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode gnome.program_init("SELinux Policy Generation Tool", "5") version = "1.0" sys.path.append('/usr/share/system-config-selinux') sys.path.append('.') # From John Hunter http://www.daa.com.au/pipermail/pygtk/2003-February/004454.html def foreach(model, path, iter, selected): selected.append(model.get_value(iter, 0)) ## ## Pull in the Glade file ## if os.access("polgen.glade", os.F_OK): xml = gtk.glade.XML ("polgen.glade", domain=PROGNAME) else: xml = gtk.glade.XML ("/usr/share/system-config-selinux/polgen.glade", domain=PROGNAME) FILE = 1 DIR = 2 class childWindow: START_PAGE = 0 SELECT_TYPE_PAGE = 0 APP_PAGE = 1 EXISTING_USER_PAGE = 2 TRANSITION_PAGE = 3 USER_TRANSITION_PAGE = 4 ADMIN_PAGE = 5 ROLE_PAGE = 6 IN_NET_PAGE = 7 OUT_NET_PAGE = 8 COMMON_APPS_PAGE = 9 FILES_PAGE = 10 BOOLEAN_PAGE = 11 SELECT_DIR_PAGE = 12 FINISH_PAGE = 12 def __init__(self): self.xml = xml self.notebook = xml.get_widget ("notebook") self.label_dict = {} self.tooltip_dict = {} label = xml.get_widget ("select_label") self.label_dict[label] = label.get_text() label = xml.get_widget ("select_user_roles_label") self.label_dict[label] = label.get_text() label = xml.get_widget ("select_dir_label") self.label_dict[label] = label.get_text() label = xml.get_widget ("select_domain_admin_label") self.label_dict[label] = label.get_text() label = xml.get_widget ("select_in_label") self.label_dict[label] = label.get_text() label = xml.get_widget ("select_out_label") self.label_dict[label] = label.get_text() label = xml.get_widget ("select_common_label") self.label_dict[label] = label.get_text() label = xml.get_widget ("select_manages_label") self.label_dict[label] = label.get_text() label = xml.get_widget ("select_booleans_label") self.label_dict[label] = label.get_text() label = xml.get_widget ("existing_user_treeview") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("transition_treeview") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("in_tcp_all_checkbutton") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("in_tcp_reserved_checkbutton") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("in_tcp_unreserved_checkbutton") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("in_tcp_entry") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("in_udp_all_checkbutton") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("in_udp_reserved_checkbutton") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("in_udp_unreserved_checkbutton") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("in_udp_entry") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("out_tcp_entry") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("out_udp_entry") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("out_tcp_all_checkbutton") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("out_udp_all_checkbutton") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("boolean_treeview") self.tooltip_dict[label] = label.get_tooltip_text() label = xml.get_widget ("write_treeview") self.tooltip_dict[label] = label.get_tooltip_text() try: self.all_types = generate.get_all_types() self.all_modules = get_all_modules() self.all_roles = generate.get_all_roles() self.all_users = generate.get_all_users() except RuntimeError, e: self.all_types = [] self.all_modules = [] self.all_roles = [] self.all_users = [] self.error(str(e)) self.name="" xml.signal_connect("on_delete_clicked", self.delete) xml.signal_connect("on_delete_boolean_clicked", self.delete_boolean) xml.signal_connect("on_exec_select_clicked", self.exec_select) xml.signal_connect("on_init_script_select_clicked", self.init_script_select) xml.signal_connect("on_add_clicked", self.add) xml.signal_connect("on_add_boolean_clicked", self.add_boolean) xml.signal_connect("on_add_dir_clicked", self.add_dir) xml.signal_connect("on_about_clicked", self.on_about_clicked) xml.get_widget ("cancel_button").connect("clicked",self.quit) self.forward_button = xml.get_widget ("forward_button") self.forward_button.connect("clicked",self.forward) self.back_button = xml.get_widget ("back_button") self.back_button.connect("clicked",self.back) self.boolean_dialog = xml.get_widget ("boolean_dialog") self.boolean_name_entry = xml.get_widget ("boolean_name_entry") self.boolean_description_entry = xml.get_widget ("boolean_description_entry") self.pages={} for i in generate.USERS: self.pages[i] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ] self.pages[generate.RUSER] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.ADMIN_PAGE, self.USER_TRANSITION_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ] self.pages[generate.LUSER] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ] self.pages[generate.SANDBOX] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE] self.pages[generate.EUSER] = [ self.SELECT_TYPE_PAGE, self.EXISTING_USER_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ] for i in generate.APPLICATIONS: self.pages[i] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE] self.pages[generate.USER] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.USER_TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ] self.current_page = 0 self.back_button.set_sensitive(0) self.network_buttons = {} self.in_tcp_all_checkbutton = xml.get_widget ("in_tcp_all_checkbutton") self.in_tcp_reserved_checkbutton = xml.get_widget ("in_tcp_reserved_checkbutton") self.in_tcp_unreserved_checkbutton = xml.get_widget ("in_tcp_unreserved_checkbutton") self.in_tcp_entry = self.xml.get_widget("in_tcp_entry") self.network_buttons[self.in_tcp_all_checkbutton] = [ self.in_tcp_reserved_checkbutton, self.in_tcp_unreserved_checkbutton, self.in_tcp_entry ] self.out_tcp_all_checkbutton = xml.get_widget ("out_tcp_all_checkbutton") self.out_tcp_reserved_checkbutton = xml.get_widget ("out_tcp_reserved_checkbutton") self.out_tcp_unreserved_checkbutton = xml.get_widget ("out_tcp_unreserved_checkbutton") self.out_tcp_entry = self.xml.get_widget("out_tcp_entry") self.network_buttons[self.out_tcp_all_checkbutton] = [ self.out_tcp_entry ] self.in_udp_all_checkbutton = xml.get_widget ("in_udp_all_checkbutton") self.in_udp_reserved_checkbutton = xml.get_widget ("in_udp_reserved_checkbutton") self.in_udp_unreserved_checkbutton = xml.get_widget ("in_udp_unreserved_checkbutton") self.in_udp_entry = self.xml.get_widget("in_udp_entry") self.network_buttons[self.in_udp_all_checkbutton] = [ self.in_udp_reserved_checkbutton, self.in_udp_unreserved_checkbutton, self.in_udp_entry ] self.out_udp_all_checkbutton = xml.get_widget ("out_udp_all_checkbutton") self.out_udp_entry = self.xml.get_widget("out_udp_entry") self.network_buttons[self.out_udp_all_checkbutton] = [ self.out_udp_entry ] for b in self.network_buttons.keys(): b.connect("clicked",self.network_all_clicked) self.boolean_treeview = self.xml.get_widget("boolean_treeview") self.boolean_store = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_STRING) self.boolean_treeview.set_model(self.boolean_store) self.boolean_store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Name"), gtk.CellRendererText(), text = 0) self.boolean_treeview.append_column(col) col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text = 1) self.boolean_treeview.append_column(col) self.role_treeview = self.xml.get_widget("role_treeview") self.role_store = gtk.ListStore(gobject.TYPE_STRING) self.role_treeview.set_model(self.role_store) self.role_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.role_store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Role"), gtk.CellRendererText(), text = 0) self.role_treeview.append_column(col) self.existing_user_treeview = self.xml.get_widget("existing_user_treeview") self.existing_user_store = gtk.ListStore(gobject.TYPE_STRING) self.existing_user_treeview.set_model(self.existing_user_store) self.existing_user_store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Existing_User"), gtk.CellRendererText(), text = 0) self.existing_user_treeview.append_column(col) for i in self.all_roles: iter = self.role_store.append() self.role_store.set_value(iter, 0, i[:-2]) self.in_tcp_reserved_checkbutton = xml.get_widget ("in_tcp_reserved_checkbutton") self.transition_treeview = self.xml.get_widget("transition_treeview") self.transition_store = gtk.ListStore(gobject.TYPE_STRING) self.transition_treeview.set_model(self.transition_store) self.transition_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.transition_store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text = 0) self.transition_treeview.append_column(col) self.user_transition_treeview = self.xml.get_widget("user_transition_treeview") self.user_transition_store = gtk.ListStore(gobject.TYPE_STRING) self.user_transition_treeview.set_model(self.user_transition_store) self.user_transition_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.user_transition_store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text = 0) self.user_transition_treeview.append_column(col) for i in self.all_users: iter = self.user_transition_store.append() self.user_transition_store.set_value(iter, 0, i[:-2]) iter = self.existing_user_store.append() self.existing_user_store.set_value(iter, 0, i[:-2]) self.admin_treeview = self.xml.get_widget("admin_treeview") self.admin_store = gtk.ListStore(gobject.TYPE_STRING) self.admin_treeview.set_model(self.admin_store) self.admin_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.admin_store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text = 0) self.admin_treeview.append_column(col) try: for u in sepolicy.interface.get_user(): iter = self.transition_store.append() self.transition_store.set_value(iter, 0, u) for a in sepolicy.interface.get_admin(): iter = self.admin_store.append() self.admin_store.set_value(iter, 0, a) except ValueError,e: self.error(e.message) def confine_application(self): return self.get_type() in generate.APPLICATIONS def forward(self, arg): type = self.get_type() if self.current_page == self.START_PAGE: self.back_button.set_sensitive(1) if self.pages[type][self.current_page] == self.SELECT_TYPE_PAGE: if self.on_select_type_page_next(): return if self.pages[type][self.current_page] == self.IN_NET_PAGE: if self.on_in_net_page_next(): return if self.pages[type][self.current_page] == self.OUT_NET_PAGE: if self.on_out_net_page_next(): return if self.pages[type][self.current_page] == self.APP_PAGE: if self.on_name_page_next(): return if self.pages[type][self.current_page] == self.EXISTING_USER_PAGE: if self.on_existing_user_page_next(): return if self.pages[type][self.current_page] == self.SELECT_DIR_PAGE: outputdir = self.output_entry.get_text() if not os.path.isdir(outputdir): self.error(_("%s must be a directory") % outputdir ) return False if self.pages[type][self.current_page] == self.FINISH_PAGE: self.generate_policy() self.xml.get_widget ("cancel_button").set_label(gtk.STOCK_CLOSE) else: self.current_page = self.current_page + 1 self.notebook.set_current_page(self.pages[type][self.current_page]) if self.pages[type][self.current_page] == self.FINISH_PAGE: self.forward_button.set_label(gtk.STOCK_APPLY) def back(self,arg): type = self.get_type() if self.pages[type][self.current_page] == self.FINISH_PAGE: self.forward_button.set_label(gtk.STOCK_GO_FORWARD) self.current_page = self.current_page - 1 self.notebook.set_current_page(self.pages[type][self.current_page]) if self.pages[type][self.current_page] == self.START_PAGE: self.back_button.set_sensitive(0) def network_all_clicked(self, button): active = button.get_active() for b in self.network_buttons[button]: b.set_sensitive(not active) def verify(self, message, title="" ): dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_YES_NO, message) dlg.set_title(title) dlg.set_position(gtk.WIN_POS_MOUSE) dlg.show_all() rc = dlg.run() dlg.destroy() return rc def info(self, message): dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, message) dlg.set_position(gtk.WIN_POS_MOUSE) dlg.show_all() dlg.run() dlg.destroy() def error(self, message): dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, message) dlg.set_position(gtk.WIN_POS_MOUSE) dlg.show_all() dlg.run() dlg.destroy() def get_name(self): if self.existing_user_radiobutton.get_active(): store, iter = self.existing_user_treeview.get_selection().get_selected() if iter == None: raise ValueError(_("You must select a user")) return store.get_value(iter, 0) else: return self.name_entry.get_text() def get_type(self): if self.sandbox_radiobutton.get_active(): return generate.SANDBOX if self.cgi_radiobutton.get_active(): return generate.CGI if self.user_radiobutton.get_active(): return generate.USER if self.init_radiobutton.get_active(): return generate.DAEMON if self.dbus_radiobutton.get_active(): return generate.DBUS if self.inetd_radiobutton.get_active(): return generate.INETD if self.login_user_radiobutton.get_active(): return generate.LUSER if self.admin_user_radiobutton.get_active(): return generate.AUSER if self.xwindows_user_radiobutton.get_active(): return generate.XUSER if self.terminal_user_radiobutton.get_active(): return generate.TUSER if self.root_user_radiobutton.get_active(): return generate.RUSER if self.existing_user_radiobutton.get_active(): return generate.EUSER def generate_policy(self, *args): outputdir = self.output_entry.get_text() try: my_policy=generate.policy(self.get_name(), self.get_type()) iter= self.boolean_store.get_iter_first() while(iter): my_policy.add_boolean(self.boolean_store.get_value(iter, 0), self.boolean_store.get_value(iter, 1)) iter= self.boolean_store.iter_next(iter) if self.get_type() in generate.APPLICATIONS: my_policy.set_program(self.exec_entry.get_text()) my_policy.gen_symbols() my_policy.set_use_syslog(self.syslog_checkbutton.get_active() == 1) my_policy.set_use_tmp(self.tmp_checkbutton.get_active() == 1) my_policy.set_use_uid(self.uid_checkbutton.get_active() == 1) my_policy.set_use_pam(self.pam_checkbutton.get_active() == 1) my_policy.set_use_dbus(self.dbus_checkbutton.get_active() == 1) my_policy.set_use_audit(self.audit_checkbutton.get_active() == 1) my_policy.set_use_terminal(self.terminal_checkbutton.get_active() == 1) my_policy.set_use_mail(self.mail_checkbutton.get_active() == 1) if self.get_type() is generate.DAEMON: my_policy.set_init_script(self.init_script_entry.get_text()) if self.get_type() == generate.USER: selected = [] self.user_transition_treeview.get_selection().selected_foreach(foreach, selected) my_policy.set_transition_users(selected) else: if self.get_type() == generate.RUSER: selected = [] self.admin_treeview.get_selection().selected_foreach(foreach, selected) my_policy.set_admin_domains(selected) selected = [] self.user_transition_treeview.get_selection().selected_foreach(foreach, selected) my_policy.set_transition_users(selected) else: selected = [] self.transition_treeview.get_selection().selected_foreach(foreach, selected) my_policy.set_transition_domains(selected) selected = [] self.role_treeview.get_selection().selected_foreach(foreach, selected) my_policy.set_admin_roles(selected) my_policy.set_in_tcp(self.in_tcp_all_checkbutton.get_active(), self.in_tcp_reserved_checkbutton.get_active(), self.in_tcp_unreserved_checkbutton.get_active(), self.in_tcp_entry.get_text()) my_policy.set_in_udp(self.in_udp_all_checkbutton.get_active(), self.in_udp_reserved_checkbutton.get_active(), self.in_udp_unreserved_checkbutton.get_active(), self.in_udp_entry.get_text()) my_policy.set_out_tcp(self.out_tcp_all_checkbutton.get_active(), self.out_tcp_entry.get_text()) my_policy.set_out_udp(self.out_udp_all_checkbutton.get_active(), self.out_udp_entry.get_text()) iter= self.store.get_iter_first() while(iter): if self.store.get_value(iter, 1) == FILE: my_policy.add_file(self.store.get_value(iter, 0)) else: my_policy.add_dir(self.store.get_value(iter, 0)) iter= self.store.iter_next(iter) self.info(my_policy.generate(outputdir)) return False except ValueError, e: self.error(e.message) def delete(self, args): store, iter = self.view.get_selection().get_selected() if iter != None: store.remove(iter) self.view.get_selection().select_path ((0,)) def delete_boolean(self, args): store, iter = self.boolean_treeview.get_selection().get_selected() if iter != None: store.remove(iter) self.boolean_treeview.get_selection().select_path ((0,)) def add_boolean(self,type): self.boolean_name_entry.set_text("") self.boolean_description_entry.set_text("") rc = self.boolean_dialog.run() self.boolean_dialog.hide() if rc == gtk.RESPONSE_CANCEL: return iter = self.boolean_store.append() self.boolean_store.set_value(iter, 0, self.boolean_name_entry.get_text()) self.boolean_store.set_value(iter, 1, self.boolean_description_entry.get_text()) def __add(self,type): rc = self.file_dialog.run() self.file_dialog.hide() if rc == gtk.RESPONSE_CANCEL: return for i in self.file_dialog.get_filenames(): iter = self.store.append() self.store.set_value(iter, 0, i) self.store.set_value(iter, 1, type) def exec_select(self, args): self.file_dialog.set_select_multiple(0) self.file_dialog.set_title(_("Select executable file to be confined.")) self.file_dialog.set_action(gtk.FILE_CHOOSER_ACTION_OPEN) self.file_dialog.set_current_folder("/usr/sbin") rc = self.file_dialog.run() self.file_dialog.hide() if rc == gtk.RESPONSE_CANCEL: return self.exec_entry.set_text(self.file_dialog.get_filename()) def init_script_select(self, args): self.file_dialog.set_select_multiple(0) self.file_dialog.set_title(_("Select init script file to be confined.")) self.file_dialog.set_action(gtk.FILE_CHOOSER_ACTION_OPEN) self.file_dialog.set_current_folder("/etc/rc.d/init.d") rc = self.file_dialog.run() self.file_dialog.hide() if rc == gtk.RESPONSE_CANCEL: return self.init_script_entry.set_text(self.file_dialog.get_filename()) def add(self, args): self.file_dialog.set_title(_("Select file(s) that confined application creates or writes")) self.file_dialog.set_current_folder("/") self.file_dialog.set_action(gtk.FILE_CHOOSER_ACTION_OPEN) self.file_dialog.set_select_multiple(1) self.__add(FILE) def add_dir(self, args): self.file_dialog.set_title(_("Select directory(s) that the confined application owns and writes into")) self.file_dialog.set_current_folder("/") self.file_dialog.set_select_multiple(1) self.file_dialog.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) self.__add(DIR) def on_about_clicked(self, args): dlg = xml.get_widget ("about_dialog") dlg.run () dlg.hide () def quit(self, args): gtk.main_quit() def setupScreen(self): # Bring in widgets from glade file. self.mainWindow = self.xml.get_widget("main_window") self.druid = self.xml.get_widget("druid") self.type = 0 self.name_entry = self.xml.get_widget("name_entry") self.name_entry.connect("insert_text",self.on_name_entry_changed) self.name_entry.connect("focus_out_event",self.on_focus_out_event) self.exec_entry = self.xml.get_widget("exec_entry") self.exec_button = self.xml.get_widget("exec_button") self.init_script_entry = self.xml.get_widget("init_script_entry") self.init_script_button = self.xml.get_widget("init_script_button") self.output_entry = self.xml.get_widget("output_entry") self.output_entry.set_text(os.getcwd()) self.xml.get_widget("output_button").connect("clicked",self.output_button_clicked) self.xwindows_user_radiobutton = self.xml.get_widget("xwindows_user_radiobutton") self.terminal_user_radiobutton = self.xml.get_widget("terminal_user_radiobutton") self.root_user_radiobutton = self.xml.get_widget("root_user_radiobutton") self.login_user_radiobutton = self.xml.get_widget("login_user_radiobutton") self.admin_user_radiobutton = self.xml.get_widget("admin_user_radiobutton") self.existing_user_radiobutton = self.xml.get_widget("existing_user_radiobutton") self.user_radiobutton = self.xml.get_widget("user_radiobutton") self.init_radiobutton = self.xml.get_widget("init_radiobutton") self.inetd_radiobutton = self.xml.get_widget("inetd_radiobutton") self.dbus_radiobutton = self.xml.get_widget("dbus_radiobutton") self.cgi_radiobutton = self.xml.get_widget("cgi_radiobutton") self.sandbox_radiobutton = self.xml.get_widget("sandbox_radiobutton") self.tmp_checkbutton = self.xml.get_widget("tmp_checkbutton") self.uid_checkbutton = self.xml.get_widget("uid_checkbutton") self.pam_checkbutton = self.xml.get_widget("pam_checkbutton") self.dbus_checkbutton = self.xml.get_widget("dbus_checkbutton") self.audit_checkbutton = self.xml.get_widget("audit_checkbutton") self.terminal_checkbutton = self.xml.get_widget("terminal_checkbutton") self.mail_checkbutton = self.xml.get_widget("mail_checkbutton") self.syslog_checkbutton = self.xml.get_widget("syslog_checkbutton") self.view = self.xml.get_widget("write_treeview") self.file_dialog = self.xml.get_widget("filechooserdialog") self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT) self.view.set_model(self.store) col = gtk.TreeViewColumn("", gtk.CellRendererText(), text = 0) col.set_resizable(True) self.view.append_column(col) self.view.get_selection().select_path ((0,)) def output_button_clicked(self, *args): self.file_dialog.set_title(_("Select directory to generate policy files in")) self.file_dialog.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) self.file_dialog.set_select_multiple(0) rc = self.file_dialog.run() self.file_dialog.hide() if rc == gtk.RESPONSE_CANCEL: return self.output_entry.set_text(self.file_dialog.get_filename()) def on_name_entry_changed(self, entry, text, size, position): if text.find(" ") >= 0: entry.emit_stop_by_name("insert_text") def on_focus_out_event(self, entry, third): name = entry.get_text() if self.name != name: if name in self.all_types: if self.verify(_("Type %s_t already defined in current policy.\nDo you want to continue?") % name, _("Verify Name")) == gtk.RESPONSE_NO: entry.set_text("") return False if name in self.all_modules: if self.verify(_("Module %s.pp already loaded in current policy.\nDo you want to continue?") % name, _("Verify Name")) == gtk.RESPONSE_NO: entry.set_text("") return False file = "/etc/rc.d/init.d/" + name if os.path.isfile(file) and self.init_script_entry.get_text() == "": self.init_script_entry.set_text(file) file = "/usr/sbin/" + name if os.path.isfile(file) and self.exec_entry.get_text() == "": self.exec_entry.set_text(file) self.name = name return False def on_in_net_page_next(self, *args): try: generate.verify_ports(self.in_tcp_entry.get_text()) generate.verify_ports(self.in_udp_entry.get_text()) except ValueError, e: self.error(e.message) return True def on_out_net_page_next(self, *args): try: generate.verify_ports(self.out_tcp_entry.get_text()) generate.verify_ports(self.out_udp_entry.get_text()) except ValueError, e: self.error(e.message) return True def on_select_type_page_next(self, *args): self.exec_entry.set_sensitive(self.confine_application()) self.exec_button.set_sensitive(self.confine_application()) self.init_script_entry.set_sensitive(self.init_radiobutton.get_active()) self.init_script_button.set_sensitive(self.init_radiobutton.get_active()) def on_existing_user_page_next(self, *args): store, iter = self.view.get_selection().get_selected() if iter != None: self.error(_("You must select a user")) return True def on_name_page_next(self, *args): name=self.name_entry.get_text() if not name.isalnum(): self.error(_("You must add a name made up of letters and numbers and containing no spaces.")) return True for i in self.label_dict: text = '%s' % (self.label_dict[i] % ("'" + name + "'")) i.set_markup(text) for i in self.tooltip_dict: text = self.tooltip_dict[i] % ("'" + name + "'") i.set_tooltip_text(text) if self.confine_application(): exe = self.exec_entry.get_text() if exe == "": self.error(_("You must enter a executable")) return True policy=generate.policy(name, self.get_type()) policy.set_program(exe) policy.gen_writeable() policy.gen_symbols() for f in policy.files.keys(): iter = self.store.append() self.store.set_value(iter, 0, f) self.store.set_value(iter, 1, FILE) for f in policy.dirs.keys(): iter = self.store.append() self.store.set_value(iter, 0, f) self.store.set_value(iter, 1, DIR) self.tmp_checkbutton.set_active(policy.use_tmp) self.uid_checkbutton.set_active(policy.use_uid) self.pam_checkbutton.set_active(policy.use_pam) self.dbus_checkbutton.set_active(policy.use_dbus) self.audit_checkbutton.set_active(policy.use_audit) self.terminal_checkbutton.set_active(policy.use_terminal) self.mail_checkbutton.set_active(policy.use_mail) self.syslog_checkbutton.set_active(policy.use_syslog) def stand_alone(self): desktopName = _("Configue SELinux") self.setupScreen() self.mainWindow.connect("destroy", self.quit) self.mainWindow.show_all() gtk.main() if __name__ == "__main__": signal.signal (signal.SIGINT, signal.SIG_DFL) app = childWindow() app.stand_alone() policycoreutils-2.3/gui/portsPage.py000066400000000000000000000241121233221606300177070ustar00rootroot00000000000000## portsPage.py - show selinux mappings ## Copyright (C) 2006 Red Hat, Inc. ## 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., 675 Mass Ave, Cambridge, MA 02139, USA. ## Author: Dan Walsh import string import gtk import gtk.glade import os import gobject import sys import seobject import commands from semanagePage import *; ## ## I18N ## PROGNAME = "policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) TYPE_COL = 0 PROTOCOL_COL = 1 MLS_COL = 2 PORT_COL = 3 try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=False, codeset = 'utf-8') except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode class portsPage(semanagePage): def __init__(self, xml): semanagePage.__init__(self, xml, "ports", _("Network Port")) xml.signal_connect("on_group_clicked", self.on_group_clicked) self.group = False self.ports_filter = xml.get_widget("portsFilterEntry") self.ports_filter.connect("focus_out_event", self.filter_changed) self.ports_filter.connect("activate", self.filter_changed) self.ports_name_entry = xml.get_widget("portsNameEntry") self.ports_protocol_combo = xml.get_widget("portsProtocolCombo") self.ports_number_entry = xml.get_widget("portsNumberEntry") self.ports_mls_entry = xml.get_widget("portsMLSEntry") self.ports_add_button = xml.get_widget("portsAddButton") self.ports_properties_button = xml.get_widget("portsPropertiesButton") self.ports_delete_button = xml.get_widget("portsDeleteButton") liststore = self.ports_protocol_combo.get_model() iter = liststore.get_iter_first() self.ports_protocol_combo.set_active_iter(iter) self.init_store() self.edit = True self.load() def filter_changed(self, *arg): filter = arg[0].get_text() if filter != self.filter: if self.edit: self.load(filter) else: self.group_load(filter) def init_store(self): self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING , gobject.TYPE_STRING) self.view.set_model(self.store) self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) self.view.set_search_equal_func(self.search) col = gtk.TreeViewColumn(_("SELinux Port\nType"), gtk.CellRendererText(), text = TYPE_COL) col.set_sort_column_id(TYPE_COL) col.set_resizable(True) self.view.append_column(col) self.store.set_sort_column_id(TYPE_COL, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("Protocol"), gtk.CellRendererText(), text = PROTOCOL_COL) col.set_sort_column_id(PROTOCOL_COL) col.set_resizable(True) self.view.append_column(col) self.mls_col = gtk.TreeViewColumn(_("MLS/MCS\nLevel"), gtk.CellRendererText(), text = MLS_COL) self.mls_col.set_resizable(True) self.mls_col.set_sort_column_id(MLS_COL) self.view.append_column(self.mls_col) col = gtk.TreeViewColumn(_("Port"), gtk.CellRendererText(), text = PORT_COL) col.set_sort_column_id(PORT_COL) col.set_resizable(True) self.view.append_column(col) self.store.set_sort_func(PORT_COL,self.sort_int, "") def sort_int(self, treemodel, iter1, iter2, user_data): try: p1 = int(treemodel.get_value(iter1,PORT_COL).split('-')[0]) p2 = int(treemodel.get_value(iter2,PORT_COL).split('-')[0]) if p1 > p2: return 1 if p1 == p2: return 0 return -1 except: return 0 def load(self,filter = ""): self.filter=filter self.port = seobject.portRecords() dict = self.port.get_all(self.local) keys = dict.keys() keys.sort() self.store.clear() for k in keys: if not (self.match(str(k[0]), filter) or self.match(dict[k][0], filter) or self.match(k[2], filter) or self.match(dict[k][1], filter) or self.match(dict[k][1], filter)): continue iter = self.store.append() if k[0] == k[1]: self.store.set_value(iter, PORT_COL, k[0]) else: rec = "%s-%s" % k[:2] self.store.set_value(iter, PORT_COL, rec) self.store.set_value(iter, TYPE_COL, dict[k][0]) self.store.set_value(iter, PROTOCOL_COL, k[2]) self.store.set_value(iter, MLS_COL, dict[k][1]) self.view.get_selection().select_path ((0,)) def group_load(self, filter = ""): self.filter=filter self.port = seobject.portRecords() dict = self.port.get_all_by_type(self.local) keys = dict.keys() keys.sort() self.store.clear() for k in keys: ports_string = ", ".join(dict[k]) if not (self.match(ports_string, filter) or self.match(k[0], filter) or self.match(k[1], filter) ): continue iter = self.store.append() self.store.set_value(iter, TYPE_COL, k[0]) self.store.set_value(iter, PROTOCOL_COL, k[1]) self.store.set_value(iter, PORT_COL, ports_string) self.store.set_value(iter, MLS_COL, "") self.view.get_selection().select_path ((0,)) def propertiesDialog(self): if self.edit: semanagePage.propertiesDialog(self) def dialogInit(self): store, iter = self.view.get_selection().get_selected() self.ports_number_entry.set_text(store.get_value(iter, PORT_COL)) self.ports_number_entry.set_sensitive(False) self.ports_protocol_combo.set_sensitive(False) self.ports_name_entry.set_text(store.get_value(iter, TYPE_COL)) self.ports_mls_entry.set_text(store.get_value(iter, MLS_COL)) protocol = store.get_value(iter, PROTOCOL_COL) liststore = self.ports_protocol_combo.get_model() iter = liststore.get_iter_first() while iter != None and liststore.get_value(iter,0) != protocol: iter = liststore.iter_next(iter) if iter != None: self.ports_protocol_combo.set_active_iter(iter) def dialogClear(self): self.ports_number_entry.set_text("") self.ports_number_entry.set_sensitive(True) self.ports_protocol_combo.set_sensitive(True) self.ports_name_entry.set_text("") self.ports_mls_entry.set_text("s0") def delete(self): store, iter = self.view.get_selection().get_selected() port = store.get_value(iter, PORT_COL) protocol = store.get_value(iter, 1) try: self.wait() (rc, out) = commands.getstatusoutput("semanage port -d -p %s %s" % (protocol, port)) self.ready() if rc != 0: return self.error(out) store.remove(iter) self.view.get_selection().select_path ((0,)) except ValueError, e: self.error(e.args[0]) def add(self): target = self.ports_name_entry.get_text().strip() mls = self.ports_mls_entry.get_text().strip() port_number = self.ports_number_entry.get_text().strip() if port_number == "": port_number = "1" for i in port_number.split("-"): if not i.isdigit(): self.error(_("Port number \"%s\" is not valid. 0 < PORT_NUMBER < 65536 ") % port_number ) return False list_model = self.ports_protocol_combo.get_model() iter = self.ports_protocol_combo.get_active_iter() protocol = list_model.get_value(iter,0) self.wait() (rc, out) = commands.getstatusoutput("semanage port -a -p %s -r %s -t %s %s" % (protocol, mls, target, port_number)) self.ready() if rc != 0: self.error(out) return False iter = self.store.append() self.store.set_value(iter, TYPE_COL, target) self.store.set_value(iter, PORT_COL, port_number) self.store.set_value(iter, PROTOCOL_COL, protocol) self.store.set_value(iter, MLS_COL, mls) def modify(self): target = self.ports_name_entry.get_text().strip() mls = self.ports_mls_entry.get_text().strip() port_number = self.ports_number_entry.get_text().strip() list_model = self.ports_protocol_combo.get_model() iter = self.ports_protocol_combo.get_active_iter() protocol = list_model.get_value(iter,0) self.wait() (rc, out) = commands.getstatusoutput("semanage port -m -p %s -r %s -t %s %s" % (protocol, mls, target, port_number)) self.ready() if rc != 0: self.error(out) return False store, iter = self.view.get_selection().get_selected() self.store.set_value(iter, TYPE_COL, target) self.store.set_value(iter, PORT_COL, port_number) self.store.set_value(iter, PROTOCOL_COL, protocol) self.store.set_value(iter, MLS_COL, mls) def on_group_clicked(self, button): self.ports_add_button.set_sensitive(self.group) self.ports_properties_button.set_sensitive(self.group) self.ports_delete_button.set_sensitive(self.group) self.mls_col.set_visible(self.group) self.group = not self.group if self.group: button.set_label(_("List View")) self.group_load(self.filter) else: button.set_label(_("Group View")) self.load(self.filter) return True policycoreutils-2.3/gui/selinux-polgengui.8000066400000000000000000000014241233221606300211410ustar00rootroot00000000000000.TH "selinux-polgengui" "8" "8 April 2013" "System Config Tools Manual" "System Config Tools Manual" .SH NAME selinux\-polgengui \- SELinux Policy Generation Tool .SH SYNOPSIS .B selinux-polgengui .SH DESCRIPTION \fBselinux-polgengui\fP is a graphical tool, which can be used to create a framework for building SELinux Policy. .SH OPTIONS None .SH FILES \fi/usr/bin/selinux-polgengui\fP .SH Examples To run the program type: selinux-polgengui .PP .SH "SEE ALSO" .TP selinux(1), sepolicy(8), sepolicy-generate(8) .PP .SH REPORTING BUGS Report bugs to . .SH LICENSE AND AUTHORS \fBselinux-polgengui\fP is licensed under the GNU General Public License and is copyrighted by Red Hat, Inc. .br This man page was written by Daniel Walsh policycoreutils-2.3/gui/selinux-polgengui.desktop000066400000000000000000000073361233221606300224530ustar00rootroot00000000000000[Desktop Entry] Name=SELinux Policy Generation Tool Name[bn_IN]=SELinux Policy নিরà§à¦®à¦¾à¦£à§‡à¦° সামগà§à¦°à§€ Name[ca]=Eina de generació de polítiques del SELinux Name[da]=Regelsætgenereringsværktøj til SELinux Name[de]=Tool zur Erstellung von SELinux-Richtlinien Name[es]=Generador de Políticas de SELinux Name[fi]=SELinux-käytäntöjen generointityökalu Name[fr]=Outil de génération de stratégies SELinux Name[gu]=SELinux પોલિસી બનાવટ સાધન Name[hi]=SELinux पॉलिसी जनन औजार Name[it]=Tool di generazione della policy di SELinux Name[ja]=SELinux ãƒãƒªã‚·ãƒ¼ç”Ÿæˆãƒ„ール Name[kn]=SELinux ಪಾಲಿಸಿ ಉತà³à²ªà²¾à²¦à²¨à²¾ ಉಪಕರಣ Name[ko]=SELinux ì •ì±… ìƒì„± ë„구 Name[ml]=SELinux പോളിസി ഉതàµà´ªà´¾à´¦à´¨ à´ªàµà´°à´¯àµ‹à´—à´‚ Name[mr]=SELinux करार निरà¥à¤®à¤¾à¤£ साधन Name[nl]=SELinux tactiek generatie gereedschap Name[or]=SELinux ନୀତି ସୃଷà­à¬Ÿà¬¿ ଉପକରଣ Name[pa]=SELinux ਪਾਲਿਸੀ ਨਿਰਮਾਣ ਜੰਤਰ Name[pl]=NarzÄ™dzie tworzenia polityki SELinuksa Name[pt]=Ferramenta de Geração de Políticas SELinux Name[pt_BR]=Ferramenta de criação de políticas do SELinux Name[ru]=СредÑтво ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð»Ð¸Ñ‚Ð¸ÐºÐ¸ SELinux Name[sv]=Genereringsverktyg för SELinuxpolicy Name[ta]=SELinux பாலிசி உறà¯à®ªà®¤à¯à®¤à®¿ கரà¯à®µà®¿ Name[te]=SELinux నిరà±à°µà°¹à°£ Name[uk]=Утиліта генерації правил SELinux Name[zh_CN]=SELinux 策略生æˆå·¥å…· Name[zh_TW]=SELinux 政策產生工具(SELinux Policy Generation Tool) Comment=Generate SELinux policy modules Comment[bn_IN]=SELinux নিয়মনীতির মডিউল নিরà§à¦®à¦¾à¦£ করà§à¦¨ Comment[ca]=Genera els mòduls de les polítiques de SELinux Comment[da]=Generér SELinux-regelsætmodul Comment[de]=Tool zur Erstellung von SELinux-Richtlinien Comment[es]=Generar módulos de política de SELinux Comment[fi]=Generoi SELinuxin käytäntömoduuleja Comment[fr]=Génére des modules de stratégie SELinux Comment[gu]=SELinux પોલિસી મોડà«àª¯à«àª²à«‹àª¨à«‡ ઉતà«àªªàª¨à«àª¨ કરો Comment[hi]=नया पॉलिसी मॉडà¥à¤¯à¥‚ल उतà¥à¤ªà¤¨à¥à¤¨ करें Comment[it]=Genera moduli della politica di SELinux Comment[ja]=æ–°ã—ã„ãƒãƒªã‚·ãƒ¼ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã®ä½œæˆ Comment[kn]=SELinux ಪಾಲಿಸಿ ಘಟಕಗಳನà³à²¨à³ ಉತà³à²ªà²¾à²¦à²¿à²¸à³ Comment[ko]=SELinux ì •ì±… 모듈 ìƒì„± Comment[ml]=SELinux à´¯ പോളിസി ഘങàµà´™à´³àµâ€ തയàµà´¯à´¾à´±à´¾à´•àµà´•àµà´• Comment[mr]=SELinux करार घटके निरà¥à¤®à¤¾à¤£ करा Comment[nl]=Maak een SELinux tactiek module aan Comment[or]=SELinux ନୀତି à¬à¬•କାଂଶ ସୃଷà­à¬Ÿà¬¿à¬•ରନà­à¬¤à­ Comment[pa]=SELinux ਪਾਲਿਸੀ ਮੈਡਿਊਲ ਬਣਾਓ Comment[pl]=Tworzenie nowych modułów polityki SELinuksa Comment[pt]=Gerar módulos de políticas SELinux Comment[pt_BR]=Gerar módulos de política do SELinux Comment[ru]=Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð´ÑƒÐ»ÐµÐ¹ политики SELinux Comment[sv]=Generera SELinux-policymoduler Comment[ta]=SELinux கொளà¯à®•ை தொகà¯à®¤à®¿à®¯à¯ˆ உரà¯à®µà®¾à®•à¯à®•வà¯à®®à¯ Comment[te]=SELinux పాలసీ మాడà±à°¯à±‚à°³à±à°³à°¨à± à°µà±à°¦à±à°­à°µà°¿à°‚పచేయà±à°®à± Comment[uk]=Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ–Ð² контролю доÑтупу SELinux Comment[zh_CN]=ç”Ÿæˆ SELinux ç­–ç•¥æ¨¡å— Comment[zh_TW]=產生 SELinux 政策模組 StartupNotify=true Icon=system-config-selinux Exec=/usr/bin/selinux-polgengui Type=Application Terminal=false Categories=System;Security; X-Desktop-File-Install-Version=0.2 policycoreutils-2.3/gui/semanagePage.py000066400000000000000000000121431233221606300203210ustar00rootroot00000000000000## semanagePage.py - show selinux mappings ## Copyright (C) 2006 Red Hat, Inc. ## 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., 675 Mass Ave, Cambridge, MA 02139, USA. ## Author: Dan Walsh import string import gtk import gtk.glade import os import gobject import sys import seobject ## ## I18N ## PROGNAME="policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=False, codeset = 'utf-8') except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode def idle_func(): while gtk.events_pending(): gtk.main_iteration() class semanagePage: def __init__(self, xml, name, description): self.xml = xml self.window = self.xml.get_widget("mainWindow").get_root_window() self.busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH) self.ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) self.local = False self.view = xml.get_widget("%sView" % name) self.dialog = xml.get_widget("%sDialog" % name) self.filter_entry = xml.get_widget("%sFilterEntry" % name ) self.filter_entry.connect("focus_out_event", self.filter_changed) self.filter_entry.connect("activate", self.filter_changed) self.view.connect("row_activated", self.rowActivated) self.view.get_selection().connect("changed", self.itemSelected) self.description = description; def wait(self): self.window.set_cursor(self.busy_cursor) idle_func() def ready(self): self.window.set_cursor(self.ready_cursor) idle_func() def get_description(self): return self.description def itemSelected(self, args): return def filter_changed(self, *arg): filter = arg[0].get_text() if filter != self.filter: self.load(filter) def search(self, model, col, key, i): sort_col = self.store.get_sort_column_id()[0] val = model.get_value(i,sort_col) if val.lower().startswith(key.lower()): return False return True def match(self, target, filter): try: f=filter.lower() t=target.lower() if t.find(f) >= 0: return True except: pass return False def rowActivated(self, view, row, Column): self.propertiesDialog() def verify(self, message, title="" ): dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_YES_NO, message) dlg.set_title(title) dlg.set_position(gtk.WIN_POS_MOUSE) dlg.show_all() rc = dlg.run() dlg.destroy() return rc def error(self, message): dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, message) dlg.set_position(gtk.WIN_POS_MOUSE) dlg.show_all() dlg.run() dlg.destroy() def deleteDialog(self): store, iter = self.view.get_selection().get_selected() if self.verify(_("Are you sure you want to delete %s '%s'?" % (self.description, store.get_value(iter, 0))), _("Delete %s" % self.description)) == gtk.RESPONSE_YES: self.delete() def use_menus(self): return True def addDialog(self): self.dialogClear() self.dialog.set_title(_("Add %s" % self.description)) self.dialog.set_position(gtk.WIN_POS_MOUSE) while self.dialog.run() == gtk.RESPONSE_OK: try: if self.add() == False: continue break; except ValueError, e: self.error(e.args[0]) self.dialog.hide() def propertiesDialog(self): self.dialogInit() self.dialog.set_title(_("Modify %s" % self.description)) self.dialog.set_position(gtk.WIN_POS_MOUSE) while self.dialog.run() == gtk.RESPONSE_OK: try: if self.modify() == False: continue break; except ValueError, e: self.error(e.args[0]) self.dialog.hide() def on_local_clicked(self, button): self.local = not self.local if self.local: button.set_label(_("all")) else: button.set_label(_("Customized")) self.load(self.filter) return True policycoreutils-2.3/gui/sepolgen000066400000000000000000000000371233221606300171300ustar00rootroot00000000000000#!/bin/sh sepolicy generate $* policycoreutils-2.3/gui/statusPage.py000066400000000000000000000170131233221606300200650ustar00rootroot00000000000000# statusPage.py - show selinux status ## Copyright (C) 2006-2009 Red Hat, Inc. ## 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., 675 Mass Ave, Cambridge, MA 02139, USA. ## Author: Dan Walsh import string import gtk import gtk.glade import os import gobject import sys import tempfile INSTALLPATH = '/usr/share/system-config-selinux' sys.path.append(INSTALLPATH) import commands ENFORCING = 1 PERMISSIVE = 0 DISABLED = -1 modearray = ( "disabled", "permissive", "enforcing" ) SELINUXDIR = "/etc/selinux/" RELABELFILE = "/.autorelabel" ## ## I18N ## PROGNAME="policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) import selinux try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=1) except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode class statusPage: def __init__(self, xml): self.xml = xml self.needRelabel = False self.type = selinux.selinux_getpolicytype() # Bring in widgets from glade file. self.typeHBox = xml.get_widget("typeHBox") self.selinuxTypeOptionMenu = xml.get_widget("selinuxTypeOptionMenu") self.typeLabel = xml.get_widget("typeLabel") self.enabledOptionMenu = xml.get_widget("enabledOptionMenu") self.currentOptionMenu = xml.get_widget("currentOptionMenu") self.relabel_checkbutton = xml.get_widget("relabelCheckbutton") self.relabel_checkbutton.set_active(self.is_relabel()) self.relabel_checkbutton.connect("toggled", self.on_relabel_toggle) if self.get_current_mode() == ENFORCING or self.get_current_mode() == PERMISSIVE: self.currentOptionMenu.append_text(_("Permissive")) self.currentOptionMenu.append_text(_("Enforcing")) self.currentOptionMenu.set_active(self.get_current_mode()) self.currentOptionMenu.connect("changed", self.set_current_mode) self.currentOptionMenu.set_sensitive(True) else: self.currentOptionMenu.append_text(_("Disabled")) self.currentOptionMenu.set_active(0) self.currentOptionMenu.set_sensitive(False) if self.read_selinux_config() == None: self.selinuxsupport = False else: self.enabledOptionMenu.connect("changed", self.enabled_changed) # # This line must come after read_selinux_config # self.selinuxTypeOptionMenu.connect("changed", self.typemenu_changed) self.typeLabel.set_mnemonic_widget(self.selinuxTypeOptionMenu) def use_menus(self): return False def get_description(self): return _("Status") def get_current_mode(self): if selinux.is_selinux_enabled(): if selinux.security_getenforce() > 0: return ENFORCING else: return PERMISSIVE else: return DISABLED def set_current_mode(self,menu): selinux.security_setenforce(menu.get_active() == 1) def is_relabel(self): return os.access(RELABELFILE, os.F_OK) != 0 def on_relabel_toggle(self,button): if button.get_active(): fd = open(RELABELFILE,"w") fd.close() else: if os.access(RELABELFILE, os.F_OK) != 0: os.unlink(RELABELFILE) def verify(self, message): dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_YES_NO, message) dlg.set_position(gtk.WIN_POS_MOUSE) dlg.show_all() rc = dlg.run() dlg.destroy() return rc def typemenu_changed(self, menu): type = self.get_type() enabled = self.enabledOptionMenu.get_active() if self.initialtype != type: if self.verify(_("Changing the policy type will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == gtk.RESPONSE_NO: menu.set_active(self.typeHistory) return None self.relabel_checkbutton.set_active(True) self.write_selinux_config(modearray[enabled], type ) self.typeHistory = menu.get_active() def enabled_changed(self, combo): enabled = combo.get_active() type = self.get_type() if self.initEnabled != DISABLED and enabled == DISABLED: if self.verify(_("Changing to SELinux disabled requires a reboot. It is not recommended. If you later decide to turn SELinux back on, the system will be required to relabel. If you just want to see if SELinux is causing a problem on your system, you can go to permissive mode which will only log errors and not enforce SELinux policy. Permissive mode does not require a reboot Do you wish to continue?")) == gtk.RESPONSE_NO: combo.set_active(self.enabled) return None if self.initEnabled == DISABLED and enabled < 2: if self.verify(_("Changing to SELinux enabled will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == gtk.RESPONSE_NO: combo.set_active(self.enabled) return None self.relabel_checkbutton.set_active(True) self.write_selinux_config(modearray[enabled], type ) self.enabled = enabled def write_selinux_config(self, enforcing, type): path = selinux.selinux_path() + "config" backup_path = path + ".bck" fd = open(path) lines = fd.readlines() fd.close() fd = open(backup_path, "w") for l in lines: if l.startswith("SELINUX="): fd.write("SELINUX=%s\n" % enforcing) continue if l.startswith("SELINUXTYPE="): fd.write("SELINUXTYPE=%s\n" % type) continue fd.write(l) fd.close() os.rename(backup_path, path) def read_selinux_config(self): self.initialtype = selinux.selinux_getpolicytype()[1] try: self.initEnabled = selinux.selinux_getenforcemode()[1] except: self.initEnabled = False pass self.enabled = self.initEnabled self.enabledOptionMenu.set_active(self.enabled + 1 ) self.types = [] n = 0 current = n for i in os.listdir(SELINUXDIR): if os.path.isdir(SELINUXDIR+i) and os.path.isdir(SELINUXDIR+i+"/policy"): self.types.append(i) self.selinuxTypeOptionMenu.append_text(i) if i == self.initialtype: current = n n = n+1 self.selinuxTypeOptionMenu.set_active(current) self.typeHistory = current return 0 def get_type(self): return self.types[self.selinuxTypeOptionMenu.get_active()] policycoreutils-2.3/gui/system-config-selinux000077500000000000000000000001321233221606300215670ustar00rootroot00000000000000#!/bin/sh exec /usr/bin/pkexec /usr/share/system-config-selinux/system-config-selinux.py policycoreutils-2.3/gui/system-config-selinux.8000066400000000000000000000014021233221606300217330ustar00rootroot00000000000000.TH "system-config-selinux" "8" "8 April 2013" "System Config Tools Manual" "System Config Tools Manual" .SH NAME system\-config\-selinux \- SELinux Management tool .SH SYNOPSIS .B system-config-selinux .SH DESCRIPTION \fBsystem-config-selinux\fP provides a graphical interface for managing the SELinux configuration. .SH OPTIONS None .SH FILES \fi/usr/bin/system-config-selinux\fP .SH Examples To run the program type: system-config-selinux .PP .SH "SEE ALSO" .TP selinux(1), semanage(8) .PP .SH REPORTING BUGS Report bugs to . .SH LICENSE AND AUTHORS \fBsystem-config-selinux\fP is licensed under the GNU General Public License and is copyrighted by Red Hat, Inc. .br This man page was written by Daniel Walsh policycoreutils-2.3/gui/system-config-selinux.desktop000066400000000000000000000070101233221606300232360ustar00rootroot00000000000000[Desktop Entry] Name=SELinux Management Name[bn_IN]=SELinux পরিচালনা Name[da]=HÃ¥ndtering af SELinux Name[de]=SELinux-Management Name[ca]=Gestió de SELinux Name[es]=Administración de SELinux Name[fi]=SELinuxin ylläpito Name[fr]=Gestion de SELinux Name[gu]=SELinux સંચાલન Name[hi]=SELinux पà¥à¤°à¤¬à¤‚धन Name[jp]=SELinux ç®¡ç† Name[it]=Gestione di SELinux Name[kn]=SELinux ವà³à²¯à²µà²¸à³à²¥à²¾à²ªà²¨à³† Name[ko]=SELinux 관리 Name[ml]=SELinux മാനേജàµà´®àµ†à´¨àµà´±àµ Name[mr]=SELinux मॅनेजमेंट Name[nl]=SELinux beheer Name[or]=SELinux ପରିଚାଳନା Name[pa]=SELinux ਮੈਨੇਜਮੈਂਟ Name[pl]=ZarzÄ…dzanie SELinuksem Name[pt_BR]=Gerenciamento do SELinux Name[pt]=Gestão de SELinux Name[ru]=Управление SELinux Name[sv]=SELinux-hantering Name[ta]=SELinux மேலாணà¯à®®à¯ˆ Name[te]=SELinux నిరà±à°µà°¹à°£ Name[uk]=ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ SELinux Name[zh_CN]=SELinux ç®¡ç† Name[zh_TW]=SELinux ç®¡ç† Comment=Configure SELinux in a graphical setting Comment[bn_IN]=গà§à¦°à¦¾à¦«à¦¿à¦•à§à¦¯à¦¾à¦² পরিবেশে SELinux কনফিগার করà§à¦¨ Comment[ca]=Configura SELinuc an mode de preferències gràfiques Comment[da]=Konfigurér SELinux i et grafisk miljø Comment[de]=SELinux in einer grafischen Einstellung konfigurieren Comment[es]=Defina SELinux en una configuración de interfaz gráfica Comment[fi]=Tee SELinuxin asetukset graafisesti Comment[fr]=Configure SELinux dans un environnement graphique Comment[gu]=ગà«àª°àª¾àª«àª¿àª•લ સà«àª¯à«‹àªœàª¨àª®àª¾àª‚ SELinux ને રૂપરેખાંકિત કરો Comment[hi]=SELinux को आलेखी सेटिंग में विनà¥à¤¯à¤¸à¥à¤¤ करें Comment[it]=Configura SELinux in una impostazione grafica Comment[jp]=グラフィカルãªè¨­å®šç”»é¢ã§ SELinux を設定ã™ã‚‹ Comment[ko]=SELinux를 그래픽 ì‚¬ìš©ìž ì¸í„°íŽ˜ì´ìŠ¤ë¡œ 설정 Comment[kn]=SELinux ಅನà³à²¨à³ ಒಂದೠಚಿತà³à²°à²¾à²¤à³à²®à²• ಸಿದà³à²¦à²¤à³†à²¯à²²à³à²²à²¿ ಸಂರಚಿಸಿ Comment[ml]=ഒരൠഗàµà´°à´¾à´«à´¿à´•àµà´•à´²àµâ€ സജàµà´œàµ€à´•രണതàµà´¤à´¿à´²àµâ€ SELinux à´•àµà´°à´®àµ€à´•à´°à´¿à´¯àµà´•àµà´•àµà´• Comment[mr]=गà¥à¤°à¤¾à¤«à¤¿à¤•ल सेटिंगमधà¥à¤¯à¥‡ SELinux संरचीत करा Comment[nl]=Configureer SELinux in een grafische omgeving Comment[or]=SELinux କୠଆଲେଖିକ ସଂରଚନାରେ ବିନà­à­Ÿà¬¾à¬¸ କରନà­à¬¤à­ Comment[pa]=SELinux ਨੂੰ ਗਰਾਫੀਕਲ ਸੈਟਿੰਗ ਵਿੱਚ ਸੰਰਚਿਤ ਕਰੋ Comment[pl]=Konfiguracja SELinuksa w trybie graficznym Comment[pt]=Configurar o SELinux num ambiente gráfico Comment[pt_BR]=Configure o SELinux em uma configuração gráfica Comment[ru]=ÐаÑтройка SELinux в графичеÑком режиме Comment[sv]=Konfigurera SELinux i en grafisk miljö Comment[ta]=SELinux஠ஒர௠வரைகலை அமைவில௠கடà¯à®Ÿà®®à¯ˆà®•à¯à®•வà¯à®®à¯ Comment[te]=SELinuxనౠగà±à°°à°¾à°«à°¿à°•లౠఅమరà±à°ªà±à°¨à°‚దౠఆకృతీకరించà±à°®à± Comment[uk]=ЗаÑіб Ð´Ð»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ SELinux з графічним інтерфейÑом Comment[zh_CN]=在图形设置中é…ç½® SELinux Comment[zh_TW]=在圖形話設定中é…ç½® SELinux StartupNotify=true Icon=system-config-selinux Exec=/usr/bin/system-config-selinux Type=Application Terminal=false Categories=System;Security; X-Desktop-File-Install-Version=0.2 policycoreutils-2.3/gui/system-config-selinux.glade000066400000000000000000003431001233221606300226440ustar00rootroot00000000000000 5 False system-config-selinux Copyright (c)2006 Red Hat, Inc. Copyright (c) 2006 Dan Walsh <dwalsh@redhat.com> False Daniel Walsh <dwalsh@redhat.com> translator-credits system-config-selinux.png Add SELinux Login Mapping GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True False True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END True False 0 True 3 2 False 4 6 True Login Name False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 fill True SELinux User False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 1 2 fill True MLS/MCS Range False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 2 3 fill True True True True 0 True * False 1 2 0 1 True False True 1 2 1 2 fill fill True True True True 0 True * False 1 2 2 3 5 True True 0 True True Add SELinux Network Ports GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True False True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END True False 0 True 4 2 False 4 6 True Port Number False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 fill True Protocol False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 1 2 fill True SELinux Type False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 2 3 fill True True True True 0 True * False 1 2 0 1 True tcp udp False True 1 2 1 2 fill fill True True True True 0 True * False 1 2 2 3 True MLS/MCS Level False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 3 4 fill True True True True 0 True * False 1 2 3 4 5 True True 0 True True Add SELinux Login Mapping GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True False True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END True False 0 True 4 2 False 4 6 True File Specification False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 fill True File Type False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 1 2 fill True SELinux Type False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 2 3 fill True True True True 0 True * False 1 2 0 1 True all files regular file directory character device block device socket symbolic link named pipe False True 1 2 1 2 fill fill True True True True 0 True * False 1 2 2 3 True MLS False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 3 4 fill True True True True 0 True * False 1 2 3 4 5 True True 0 True True Add SELinux User GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True False True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END True False 0 True 3 2 False 4 6 True SELinux User False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 fill True MLS/MCS Range False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 1 2 fill True True True True 0 True * False 1 2 1 2 True SELinux Roles False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 2 3 fill True True True True 0 True * False 1 2 2 3 True True True True 0 True * False 1 2 0 1 5 True True 0 True True 800 500 SELinux Administration GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False system-config-selinux.png True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False True True True True GTK_SHADOW_NONE True GTK_PACK_DIRECTION_LTR GTK_PACK_DIRECTION_LTR True GNOMEUIINFO_MENU_FILE_TREE True Add True True gtk-add 1 0.5 0.5 0 0 True _Properties True True gtk-properties 1 0.5 0.5 0 0 True _Delete True True gtk-delete 1 0.5 0.5 0 0 True GNOMEUIINFO_MENU_EXIT_ITEM True GNOMEUIINFO_MENU_HELP_TREE True GNOMEUIINFO_MENU_ABOUT_ITEM BONOBO_DOCK_TOP 0 0 0 BONOBO_DOCK_ITEM_BEH_EXCLUSIVE|BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL|BONOBO_DOCK_ITEM_BEH_LOCKED True True 5 True 0 0.5 GTK_SHADOW_NONE True 0.5 0.5 1 1 0 0 12 0 True Select Management Object True False False False True False False False True <b>Select:</b> False True GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 label_item False True True False True GTK_POS_TOP False False True False 0 True 4 2 False 5 5 True System Default Enforcing Mode False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 fill True Disabled Permissive Enforcing False True 1 2 0 1 fill True Current Enforcing Mode False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 1 2 fill True False True 1 2 1 2 fill fill True System Default Policy Type: False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 2 3 fill True False True 1 2 2 3 fill fill True Select if you wish to relabel then entire file system on next reboot. Relabeling can take a very long time, depending on the size of the system. If you are changing policy types or going from disabled to enforcing, a relabel is required. True GTK_RELIEF_NORMAL True False False True True 0.5 0.5 0 0 0 0 0 0 True False 2 True gtk-refresh 4 0.5 0.5 0 0 0 False False True Relabel on next reboot. True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 False False 0 2 3 4 fill fill 0 True True False True True label37 False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab True False 0 True GTK_ORIENTATION_HORIZONTAL GTK_TOOLBAR_BOTH True True True Revert boolean setting to system default gtk-revert-to-saved True True False False True True Toggle between Customized and All Booleans Customized True gtk-find True True False False True 0 False False True False 0 True Filter False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 10 False False True True True True 0 True • False 0 True True 10 False True True True GTK_POLICY_ALWAYS GTK_POLICY_ALWAYS GTK_SHADOW_NONE GTK_CORNER_TOP_LEFT True Boolean True True False False True False False False 0 True True False True True label50 False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab True False 0 True GTK_ORIENTATION_HORIZONTAL GTK_TOOLBAR_BOTH True True True Add File Context gtk-add True True False False True True Modify File Context gtk-properties True True False False True True Delete File Context gtk-delete True True False False True True Toggle between all and customized file context Customized True gtk-find True True False False True 0 False False True False 0 True Filter False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 10 False False True True True True 0 True • False 0 True True 0 False False True True GTK_POLICY_ALWAYS GTK_POLICY_ALWAYS GTK_SHADOW_NONE GTK_CORNER_TOP_LEFT True File Labeling True True False False True False False False 0 True True False True True label38 False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab True False 0 True GTK_ORIENTATION_HORIZONTAL GTK_TOOLBAR_BOTH True True True Add SELinux User Mapping gtk-add True True False False True True Modify SELinux User Mapping gtk-properties True True False False True True Delete SELinux User Mapping gtk-delete True True False False True 0 False False True False 0 True Filter False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 10 False False True True True True 0 True • False 0 True True 5 False True True True GTK_POLICY_ALWAYS GTK_POLICY_ALWAYS GTK_SHADOW_NONE GTK_CORNER_TOP_LEFT True User Mapping True True False False True False False False 0 True True False True True label39 False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab True False 0 True GTK_ORIENTATION_HORIZONTAL GTK_TOOLBAR_BOTH True True True Add User gtk-add True True False False True True Modify User gtk-properties True True False False True True Delete User gtk-delete True True False False True 0 False False True False 0 True Filter False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 10 False False True True True True 0 True • False 0 True True 5 False True True True GTK_POLICY_ALWAYS GTK_POLICY_ALWAYS GTK_SHADOW_NONE GTK_CORNER_TOP_LEFT True SELinux User True True False False True False False False 0 True True False True True label41 False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab True False 0 True GTK_ORIENTATION_HORIZONTAL GTK_TOOLBAR_BOTH False True True Add Network Port gtk-add True True False False True True Edit Network Port gtk-properties True True False False True True Delete Network Port gtk-delete True True False False True True True True False 32 True False False True Toggle between Customized and All Ports Group View True gtk-indent True True False False True True Toggle between Customized and All Ports Customized True gtk-find True True False False True 0 False False True False 0 True Filter False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 10 False False True True True True 0 True • False 0 True True 5 False True True True GTK_POLICY_ALWAYS GTK_POLICY_ALWAYS GTK_SHADOW_NONE GTK_CORNER_TOP_LEFT True Network Port True True False False True False False False 0 True True False True True label42 False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab True False 0 True GTK_ORIENTATION_HORIZONTAL GTK_TOOLBAR_BOTH True True True Generate new policy module gtk-new True True False False True True Load policy module gtk-add True True False False True True Remove loadable policy module gtk-remove True True False False True True True True False 10 True False False True Enable/Disable additional audit rules, that are normally not reported in the log files. Enable Audit True gtk-zoom-in True True False False True 0 False False True False 0 True Filter False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 10 False False True True True True 0 True • False 0 True True 5 False True True True GTK_POLICY_ALWAYS GTK_POLICY_ALWAYS GTK_SHADOW_NONE GTK_CORNER_TOP_LEFT True Policy Module True True False False True False False False 0 True True False True True label44 False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab True False 0 True GTK_ORIENTATION_HORIZONTAL GTK_TOOLBAR_BOTH True True True Change process mode to permissive. Permissive True gtk-dialog-warning True True False False True True Change process mode to enforcing Enforcing True gtk-dialog-error True True False False True 0 False False True False 0 True Filter False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 10 False False True True True True 0 True • False 0 True True 5 False True True True GTK_POLICY_ALWAYS GTK_POLICY_ALWAYS GTK_SHADOW_NONE GTK_CORNER_TOP_LEFT True Process Domain True True False False True False False False 0 True True False True True label59 False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab True True 0 True True True True True 0 True True policycoreutils-2.3/gui/system-config-selinux.png000066400000000000000000000026471233221606300223640ustar00rootroot00000000000000‰PNG  IHDRàw=øgAMAÖØÔOX2tEXtSoftwareAdobe ImageReadyqÉe<9IDATxÚ´V]L“g~úcÿ¯6Ba‚ÕâfeÖêü™2ü‰²;ÆBË‚fËâ2ÝpKÜÅ’-xá…K”ãÅÂêH–lKüAb6þQÔ.J¡£¬2)ØVZJ©í×úî|m×fÙ²ßäé÷æûÎ{ž÷=ç9ï©„1†:²L;¡p™p€ÀúKKK£‡©oö”íÿ@"‘ô›–èlÛ¶aëV#LeZœ<ýNuŒóóó9§Ó‰p8Œ7n ¯¯‡ãããAZ…p5õtý ¸bÁÂmðMÂ÷À‹gÞ'Á‰k€¢ì]?~|~D"bff&CÖÛÛ ·ÛL‘¤ ¯äxÎÃý¬\·¹‰hò|À1ì?ZŠžžèõú A6„!¦ˆpýúuáÒ « ˆU°¬×@mªGäÞyx™Ï[)èköbß¾}P(P«Õ"T*UΩÒd³¸¸¡Ph©<+iŒB!}–,€LS‚n:Å’×ñYRéYªÇÀlCÎaTïjD[[ÛßñÔ™žÌDéGÌN%0öK'žÞ¹ŽÄ&q( iÍË× Ï\ -ÙÎù,mL®”cõ*µy†¤Ã“C _¥ÀÈm`!I5>Íã•õÀÚ=À"R’ÃËaç΢]!…ì™D†ãÀÉ `ŽdT_¥ å…jHøÙ gá8ä:¤2 x“Æ•À‚ç@‘ã8TVVŠIž†É÷;´‰(”´ZAÎ%qҸ║i¶Š¤2iBnõËËàûb_lX6ŠÖÖV455¡££åùlžó`]ô6Â*¹¼o>g7Ê•¢ËþÈT¸*tŠžóyÈTðè¶à›ÉP;–D7oc·Û100€úúz466¢¨¨H¸055…å²(ö+FñNÝ*´\²ñóBOÙž!ˆÓÉL•¤—BíxóìScI”SHÜ^²ÎÛµ´´ ¶¶çÎU%·ìIgìmDÑ’BØ­!ä MØŽLÆ/Ëš››qèÐ!S ›…vª/¥¤ö…ñc8Èé&ª½‹Nª‡+VÀh¤†d2aÇŽbN***àñx0p÷Üúñ†F>îÇËzà×1Þ˜¾*8ýß¾?Ut;üØ{o••ˆe/´Ê–Tl™Õjet V]]Í KµX¡¶oVI™ãU;h0Ñ>«'Û„‹±¬Ùý÷@ê}ö2²Ðü/ý¹%E(¬ç$/ú_…/xü%ÀI;-!ò^~ÜIEND®B`‚policycoreutils-2.3/gui/system-config-selinux.py000066400000000000000000000142441233221606300222240ustar00rootroot00000000000000#!/usr/bin/python -Es # # system-config-selinux.py - GUI for SELinux Config tool in system-config-selinux # # Dan Walsh # # Copyright 2006-2009 Red Hat, Inc. # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # import signal import string import sys try: import gtk except RuntimeError, e: print "system-config-selinux:", e print "This is a graphical application and requires DISPLAY to be set." sys.exit (1) import gtk.glade import os import gobject import gnome import statusPage import booleansPage import loginsPage import usersPage import portsPage import modulesPage import domainsPage import fcontextPage import selinux ## ## I18N ## PROGNAME="policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=False, codeset = 'utf-8') except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode gnome.program_init("SELinux Management Tool", "5") version = "1.0" sys.path.append('/usr/share/system-config-selinux') ## ## Pull in the Glade file ## if os.access("system-config-selinux.glade", os.F_OK): xml = gtk.glade.XML ("system-config-selinux.glade", domain=PROGNAME) else: xml = gtk.glade.XML ("/usr/share/system-config-selinux/system-config-selinux.glade", domain=PROGNAME) class childWindow: def __init__(self): self.tabs=[] self.xml = xml xml.signal_connect("on_quit_activate", self.destroy) xml.signal_connect("on_delete_clicked", self.delete) xml.signal_connect("on_add_clicked", self.add) xml.signal_connect("on_properties_clicked", self.properties) xml.signal_connect("on_local_clicked", self.on_local_clicked) self.add_page(statusPage.statusPage(xml)) if selinux.is_selinux_enabled() > 0: try: self.add_page(booleansPage.booleansPage(xml)) self.add_page(fcontextPage.fcontextPage(xml)) self.add_page(loginsPage.loginsPage(xml)) self.add_page(usersPage.usersPage(xml)) self.add_page(portsPage.portsPage(xml)) self.add_page(modulesPage.modulesPage(xml)) # modules self.add_page(domainsPage.domainsPage(xml)) # domains except ValueError, e: self.error(e.message) xml.signal_connect("on_quit_activate", self.destroy) xml.signal_connect("on_policy_activate", self.policy) xml.signal_connect("on_logging_activate", self.logging) xml.signal_connect("on_about_activate", self.on_about_activate) self.add_menu = xml.get_widget("add_menu_item") self.properties_menu = xml.get_widget("properties_menu_item") self.delete_menu = xml.get_widget("delete_menu_item") def error(self, message): dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, message) dlg.set_position(gtk.WIN_POS_MOUSE) dlg.show_all() dlg.run() dlg.destroy() def add_page(self, page): self.tabs.append(page) def policy(self, args): os.spawnl(os.P_NOWAIT, "/usr/share/system-config-selinux/semanagegui.py") def logging(self, args): os.spawnl(os.P_NOWAIT, "/usr/bin/seaudit") def delete(self, args): self.tabs[self.notebook.get_current_page()].deleteDialog() def add(self, args): self.tabs[self.notebook.get_current_page()].addDialog() def properties(self, args): self.tabs[self.notebook.get_current_page()].propertiesDialog() def on_local_clicked(self, button): self.tabs[self.notebook.get_current_page()].on_local_clicked(button) def on_about_activate(self, args): dlg = xml.get_widget ("aboutWindow") dlg.run () dlg.hide () def destroy(self, args): gtk.main_quit() def use_menus(self, use_menus): self.add_menu.set_sensitive(use_menus) self.properties_menu.set_sensitive(use_menus) self.delete_menu.set_sensitive(use_menus) def itemSelected(self, selection): store, rows = selection.get_selected_rows() if store != None and len(rows) > 0: self.notebook.set_current_page(rows[0][0]) self.use_menus(self.tabs[rows[0][0]].use_menus()) else: self.notebook.set_current_page(0) self.use_menus(self.tabs[0].use_menus()) def setupScreen(self): # Bring in widgets from glade file. self.mainWindow = self.xml.get_widget("mainWindow") self.notebook = self.xml.get_widget("notebook") self.view = self.xml.get_widget("selectView") self.view.get_selection().connect("changed", self.itemSelected) self.store = gtk.ListStore(gobject.TYPE_STRING) self.view.set_model(self.store) col = gtk.TreeViewColumn("", gtk.CellRendererText(), text = 0) col.set_resizable(True) self.view.append_column(col) for page in self.tabs: iter = self.store.append() self.store.set_value(iter, 0, page.get_description()) self.view.get_selection().select_path ((0,)) def stand_alone(self): desktopName = _("Configue SELinux") self.setupScreen() self.mainWindow.connect("destroy", self.destroy) self.mainWindow.show_all() gtk.main() if __name__ == "__main__": signal.signal (signal.SIGINT, signal.SIG_DFL) app = childWindow() app.stand_alone() policycoreutils-2.3/gui/usersPage.py000066400000000000000000000122501233221606300177010ustar00rootroot00000000000000## usersPage.py - show selinux mappings ## Copyright (C) 2006,2007,2008 Red Hat, Inc. ## 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., 675 Mass Ave, Cambridge, MA 02139, USA. ## Author: Dan Walsh import string import gtk import gtk.glade import os import gobject import sys import commands import seobject from semanagePage import *; ## ## I18N ## PROGNAME="policycoreutils" import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, localedir="/usr/share/locale", unicode=1) except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode class usersPage(semanagePage): def __init__(self, xml): semanagePage.__init__(self, xml, "users", _("SELinux User")) self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) self.view.set_model(self.store) self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text = 0) col.set_sort_column_id(0) col.set_resizable(True) self.view.append_column(col) col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text = 1) col.set_resizable(True) self.view.append_column(col) col = gtk.TreeViewColumn(_("SELinux Roles"), gtk.CellRendererText(), text = 2) col.set_resizable(True) self.view.append_column(col) self.load() self.selinuxUserEntry = xml.get_widget("selinuxUserEntry") self.mlsRangeEntry = xml.get_widget("mlsRangeEntry") self.selinuxRolesEntry = xml.get_widget("selinuxRolesEntry") def load(self, filter = ""): self.filter=filter self.user = seobject.seluserRecords() dict = self.user.get_all() keys = dict.keys() keys.sort() self.store.clear() for k in keys: range = seobject.translate(dict[k][2]) if not (self.match(k, filter) or self.match(dict[k][0], filter) or self.match(range, filter) or self.match(dict[k][3], filter)): continue iter = self.store.append() self.store.set_value(iter, 0, k) self.store.set_value(iter, 1, range) self.store.set_value(iter, 2, dict[k][3]) self.view.get_selection().select_path ((0,)) def delete(self): if semanagePage.delete(self) == gtk.RESPONSE_NO: return None def dialogInit(self): store, iter = self.view.get_selection().get_selected() self.selinuxUserEntry.set_text(store.get_value(iter, 0)) self.selinuxUserEntry.set_sensitive(False) self.mlsRangeEntry.set_text(store.get_value(iter, 1)) self.selinuxRolesEntry.set_text(store.get_value(iter, 2)) def dialogClear(self): self.selinuxUserEntry.set_text("") self.selinuxUserEntry.set_sensitive(True) self.mlsRangeEntry.set_text("s0") self.selinuxRolesEntry.set_text("") def add(self): user = self.selinuxUserEntry.get_text() range = self.mlsRangeEntry.get_text() roles = self.selinuxRolesEntry.get_text() self.wait() (rc, out) = commands.getstatusoutput("semanage user -a -R '%s' -r %s %s" % (roles, range, user)) self.ready() if rc != 0: self.error(out) return False iter = self.store.append() self.store.set_value(iter, 0, user) self.store.set_value(iter, 1, range) self.store.set_value(iter, 2, roles) def modify(self): user = self.selinuxUserEntry.get_text() range = self.mlsRangeEntry.get_text() roles = self.selinuxRolesEntry.get_text() self.wait() (rc, out) = commands.getstatusoutput("semanage user -m -R '%s' -r %s %s" % (roles, range, user)) self.ready() if rc != 0: self.error(out) return False self.load(self.filter) def delete(self): store, iter = self.view.get_selection().get_selected() try: user=store.get_value(iter, 0) if user == "root" or user == "user_u": raise ValueError(_("SELinux user '%s' is required") % user) self.wait() (rc, out) = commands.getstatusoutput("semanage user -d %s" % user) self.ready() if rc != 0: self.error(out) return False store.remove(iter) self.view.get_selection().select_path ((0,)) except ValueError, e: self.error(e.args[0]) policycoreutils-2.3/load_policy/000077500000000000000000000000001233221606300171035ustar00rootroot00000000000000policycoreutils-2.3/load_policy/Makefile000066400000000000000000000014701233221606300205450ustar00rootroot00000000000000# Installation directories. PREFIX ?= $(DESTDIR)/usr SBINDIR ?= $(DESTDIR)/sbin USRSBINDIR ?= $(PREFIX)/sbin MANDIR ?= $(PREFIX)/share/man LOCALEDIR ?= /usr/share/locale CFLAGS ?= -Werror -Wall -W override CFLAGS += $(LDFLAGS) -I$(PREFIX)/include -DUSE_NLS -DLOCALEDIR="\"$(LOCALEDIR)\"" -DPACKAGE="\"policycoreutils\"" LDLIBS += -lsepol -lselinux -L$(PREFIX)/lib TARGETS=$(patsubst %.c,%,$(wildcard *.c)) all: $(TARGETS) install: all -mkdir -p $(SBINDIR) install -m 755 $(TARGETS) $(SBINDIR) test -d $(MANDIR)/man8 || install -m 755 -d $(MANDIR)/man8 install -m 644 load_policy.8 $(MANDIR)/man8/ -mkdir -p $(USRSBINDIR) -ln -sf $(SBINDIR)/load_policy $(USRSBINDIR)/load_policy clean: -rm -f $(TARGETS) *.o indent: ../../scripts/Lindent $(wildcard *.[ch]) relabel: /sbin/restorecon $(SBINDIR)/load_policy policycoreutils-2.3/load_policy/load_policy.8000066400000000000000000000016271233221606300215000ustar00rootroot00000000000000.TH LOAD_POLICY "8" "May 2003" "Security Enhanced Linux" NSA .SH NAME load_policy \- load a new SELinux policy into the kernel .SH SYNOPSIS .B load_policy [\-qi] .br .SH DESCRIPTION .PP load_policy loads the installed policy file into the kernel. The existing policy boolean values are automatically preserved across policy reloads rather than being reset to the default values in the policy file. .SH "OPTIONS" .TP .B \-q suppress warning messages. .TP .B \-i initial policy load. Only use this if this is the first time policy is being loaded since boot (usually called from initramfs). .SH "EXIT STATUS" .TP .B 0 Success .TP .B 1 Invalid option .TP .B 2 Policy load failed .TP .B 3 Initial policy load failed and enforcing mode requested .SH SEE ALSO .B booleans (8), .SH AUTHORS .nf This manual page was written by Dan Walsh . The program was written by Stephen Smalley . policycoreutils-2.3/load_policy/load_policy.c000066400000000000000000000043541233221606300215530ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #ifdef USE_NLS #include /* for setlocale() */ #include /* for gettext() */ #define _(msgid) gettext (msgid) #else #define _(msgid) (msgid) #endif #ifndef PACKAGE #define PACKAGE "policycoreutils" /* the name of this package lang translation */ #endif void usage(char *progname) { fprintf(stderr, _("usage: %s [-qi]\n"), progname); exit(1); } int main(int argc, char **argv) { int ret, opt, quiet = 0, nargs, init=0, enforce=0; #ifdef USE_NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif while ((opt = getopt(argc, argv, "bqi")) > 0) { switch (opt) { case 'b': fprintf(stderr, "%s: Warning! The -b option is no longer supported, booleans are always preserved across reloads. Continuing...\n", argv[0]); break; case 'q': quiet = 1; sepol_debug(0); break; case 'i': init = 1; break; default: usage(argv[0]); } } nargs = argc - optind; if (nargs > 2) usage(argv[0]); if (nargs >= 1 && !quiet) { fprintf(stderr, "%s: Warning! Policy file argument (%s) is no longer supported, installed policy is always loaded. Continuing...\n", argv[0], argv[optind++]); } if (nargs == 2 && ! quiet) { fprintf(stderr, "%s: Warning! Boolean file argument (%s) is no longer supported, installed booleans file is always used. Continuing...\n", argv[0], argv[optind++]); } if (init) { if (is_selinux_enabled() == 1) { /* SELinux is already enabled, we should not do an initial load again */ fprintf(stderr, _("%s: Policy is already loaded and initial load requested\n"), argv[0]); exit(2); } ret = selinux_init_load_policy(&enforce); if (ret != 0 ) { if (enforce > 0) { /* SELinux in enforcing mode but load_policy failed */ fprintf(stderr, _("%s: Can't load policy and enforcing mode requested: %s\n"), argv[0], strerror(errno)); exit(3); } } } else { ret = selinux_mkload_policy(1); } if (ret < 0) { fprintf(stderr, _("%s: Can't load policy: %s\n"), argv[0], strerror(errno)); exit(2); } exit(0); } policycoreutils-2.3/man/000077500000000000000000000000001233221606300153605ustar00rootroot00000000000000policycoreutils-2.3/man/Makefile000066400000000000000000000002441233221606300170200ustar00rootroot00000000000000# Installation directories. MAN5DIR ?= $(DESTDIR)/usr/share/man/man5 all: clean: install: all mkdir -p $(MAN5DIR) install -m 644 man5/*.5 $(MAN5DIR) relabel: policycoreutils-2.3/man/man5/000077500000000000000000000000001233221606300162205ustar00rootroot00000000000000policycoreutils-2.3/man/man5/selinux_config.5000066400000000000000000000126251233221606300213300ustar00rootroot00000000000000.TH "selinux_config" "5" "18 Nov 2011" "Security Enhanced Linux" "SELinux configuration file" .SH "NAME" config \- The SELinux sub-system configuration file. .SH "DESCRIPTION" The SELinux \fIconfig\fR file controls the state of SELinux regarding: .RS .IP "1." 4 The policy enforcement status \- \fIenforcing\fR, \fIpermissive\fR or \fIdisabled\fR. .IP "2." 4 The policy name or type that forms a path to the policy to be loaded and its supporting configuration files. .IP "3." 4 How local users and booleans will be managed when the policy is loaded (note that this function was used by older releases of SELinux and is now deprecated). .IP "4." 4 How SELinux-aware login applications should behave if no valid SELinux users are configured. .IP "5." 4 Whether the system is to be relabeled or not. .RE The entries controlling these functions are described in the \fBFILE FORMAT\fR section. .sp The fully qualified path name of the SELinux configuration file is \fI/etc/selinux/config\fR. .sp If the \fIconfig\fR file is missing or corrupt, then no SELinux policy is loaded (i.e. SELinux is disabled). .sp The \fBsestatus\fR (8) command and the libselinux function \fBselinux_path\fR (3) will return the location of the \fIconfig\fR file. .SH "FILE FORMAT" The \fIconfig\fR file supports the following parameters: .sp .RS \fBSELINUX = \fIenforcing\fR | \fIpermissive\fR | \fIdisabled\fR .br \fBSELINUXTYPE = \fIpolicy_name\fR .br \fBSETLOCALDEFS = \fI0\fR | \fI1\fR .br \fBREQUIREUSERS = \fI0\fR | \fI1\fR .br \fBAUTORELABEL = \fI0\fR | \fI1\fR .RE .sp Where: .br .B SELINUX .RS This entry can contain one of three values: .RS .IP \fIenforcing\fR 4 SELinux security policy is enforced. .IP \fIpermissive\fR 4 SELinux security policy is not enforced but logs the warnings (i.e. the action is allowed to proceed). .IP \fIdisabled\fR SELinux is disabled and no policy is loaded. .RE .sp The entry can be determined using the \fBsestatus\fR(8) command or \fBselinux_getenforcemode\fR(3). .RE .sp .B SELINUXTYPE .RS The \fIpolicy_name\fR entry is used to identify the policy type, and becomes the directory name of where the policy and its configuration files are located. .sp The entry can be determined using the \fBsestatus\fR(8) command or \fBselinux_getpolicytype\fR(3). .sp The \fIpolicy_name\fR is relative to a path that is defined within the SELinux subsystem that can be retrieved by using \fBselinux_path\fR(3). An example entry retrieved by \fBselinux_path\fR(3) is: .br .RS .I /etc/selinux/ .RE .sp The \fIpolicy_name\fR is then appended to this and becomes the 'policy root' location that can be retrieved by \fBselinux_policy_root_path\fR(3). An example entry retrieved is: .RS .I /etc/selinux/targeted .RE .sp The actual binary policy is located relative to this directory and also has a policy name pre-allocated. This information can be retrieved using \fBselinux_binary_policy_path\fR(3). An example entry retrieved by \fBselinux_binary_policy_path\fR(3) is: .br .RS .I /etc/selinux/targeted/policy/policy .RE .sp The binary policy name has by convention the SELinux policy version that it supports appended to it. The maximum policy version supported by the kernel can be determined using the \fBsestatus\fR(8) command or \fBsecurity_policyvers\fR(3). An example binary policy file with the version is: .br .RS .I /etc/selinux/targeted/policy/policy.24 .RE .RE .sp .B SETLOCALDEFS .RS This entry is deprecated and should be removed or set to \fI0\fR. .sp If set to \fI1\fR, then \fBselinux_mkload_policy\fR(3) will read the local customization for booleans (see \fBbooleans\fR(5)) and users (see \fBlocal.users\fR(5)). .RE .sp .B REQUIRESEUSERS .RS This optional entry can be used to fail a login if there is no matching or default entry in the .BR seusers "(5) file or if the " seusers " file is missing. " .sp It is checked by \fBgetseuserbyname\fR(3) that is called by SELinux-aware login applications such as \fBPAM\fR(8). .sp If set to \fI0\fR or the entry missing: .RS .BR getseuserbyname "(3) will return the GNU / Linux user name as the SELinux user." .RE .sp If set to \fI1\fR: .RS .BR getseuserbyname "(3) will fail." .RE .sp The \fBgetseuserbyname\fR(3) man page should be consulted for its use. The format of the \fIseusers\fR file is shown in \fBseusers\fR(5). .sp .RE .sp .B AUTORELABEL .RS This is an optional entry that allows the file system to be relabeled. .sp If set to \fI0\fR and there is a file called \fI.autorelabel\fR in the root directory, then on a reboot, the loader will drop to a shell where a root login is required. An administrator can then manually relabel the file system. .sp If set to \fI1\fR or no entry present (the default) and there is a \fI.autorelabel\fR file in the root directory, then the file system will be automatically relabeled using \fBfixfiles \-F restore\fR .sp In both cases the \fI/.autorelabel\fR file will be removed so that relabeling is not done again. .RE .sp .SH "EXAMPLE" This example \fIconfig\fR file shows the minimum contents for a system to run SELinux in enforcing mode, with a \fIpolicy_name\fR of 'targeted': .sp .RS SELINUX = enforcing .br SELINUXTYPE = targeted .RE .SH "SEE ALSO" .BR selinux "(8), " sestatus "(8), " selinux_path "(3), " selinux_policy_root_path "(3), " selinux_binary_policy_path "(3), " getseuserbyname "(3), " PAM "(8), " fixfiles "(8), " selinux_mkload_policy "(3), " selinux_getpolicytype "(3), " security_policyvers "(3), " selinux_getenforcemode "(3), " seusers "(5), " booleans "(5), " local.users "(5) " policycoreutils-2.3/mcstrans/000077500000000000000000000000001233221606300164375ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/COPYING000066400000000000000000000431101233221606300174710ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. policycoreutils-2.3/mcstrans/ChangeLog000066400000000000000000000007101233221606300202070ustar00rootroot000000000000000.3.2 2010-07-19 * Add constraints. * Add setrans.conf man page * Fix mixed raw and translated range bug * Moved todo comments to TODO file 0.3.1-4 2009-10-16 * Add mcstransd man page 0.3.1-3 2009-09-17 * Fix init script 0.3.0 2009-02-06 * Add inverse bit support * Add color support from Eamon Walsh 0.2.1 2007-02-6 * Rewrite for Proper MLS Translations 0.1.8 2005-08-5 * Add Chad Hanson Patch for MLS 0.1.0 2005-08-5 * Initial public release. policycoreutils-2.3/mcstrans/Makefile000066400000000000000000000003331233221606300200760ustar00rootroot00000000000000all: $(MAKE) -C src $(MAKE) -C utils install: $(MAKE) -C src install # $(MAKE) -C utils install $(MAKE) -C man install clean: rm -f *~ \#* $(MAKE) -C src clean $(MAKE) -C utils clean $(MAKE) -C man clean policycoreutils-2.3/mcstrans/TODO000066400000000000000000000007711233221606300171340ustar00rootroot00000000000000TODO List for mcstrans: In compute_raw_from_trans look for conflicting bit patterns and report errors. In emit_whitespace look at whitespace characters for any regex special character and escape them. Make prefixes and suffixes optional (ex. SECRET REL AUS == SECRET AUS). compute_trans_from_raw is an expensive operation that needs to be sped up or threaded so that mcstrans can respond to other requests more quickly. Reevaluate the means of determining whether inverse bits are used in a domain. policycoreutils-2.3/mcstrans/VERSION000066400000000000000000000000061233221606300175030ustar00rootroot000000000000000.3.3 policycoreutils-2.3/mcstrans/man/000077500000000000000000000000001233221606300172125ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/man/Makefile000066400000000000000000000003021233221606300206450ustar00rootroot00000000000000# Installation directories. MAN8DIR ?= $(DESTDIR)/usr/share/man/man8 all: install: all mkdir -p $(MAN8DIR) install -m 644 man8/*.8 $(MAN8DIR) clean: -rm -f *~ \#* -rm -f man8/*~ man8/\#* policycoreutils-2.3/mcstrans/man/man8/000077500000000000000000000000001233221606300200555ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/man/man8/mcs.8000066400000000000000000000023511233221606300207310ustar00rootroot00000000000000.TH "mcs" "8" "8 Sep 2005" "dwalsh@redhat.com" "mcs documentation" .SH "NAME" mcs \- Multi-Category System .SH "DESCRIPTION" MCS (Multiple Category System) allows users to label files on their system within administrator defined categories. It then uses SELinux Mandatory Access Control to protect those files. MCS is a discretionary model to allow users to mark their data with additional tags that further restrict access. The only mandatory aspect is authorizing users for categories by defining their clearance in policy. However, MCS is similar to MLS and exercises the same code paths and share the same support infrastructure. They just differ in their specific configuration. The .I /etc/selinux/{SELINUXTYPE}/setrans.conf configuration file translates the labels on disk to human readable form. Administrators can define any labels they want in this file. Certain applications like printing and auditing will use these labels to identify the files. By setting a category on a file you will prevent other applications/services from having access to the files. .P Examples of file labels would be PatientRecord, CompanyConfidential etc. .SH "SEE ALSO" selinux(8), chcon(1) .SH FILES /etc/selinux/{SELINUXTYPE}/setrans.conf policycoreutils-2.3/mcstrans/man/man8/mcstransd.8000066400000000000000000000016001233221606300221410ustar00rootroot00000000000000.TH "mcstransd" "8" "16 Oct 2009" "dwalsh@redhat.com" "mcs documentation" .SH "NAME" mcstransd \- MCS (Multiple Category System) daemon. Translates SELinux MCS/MLS labels to human readable form. .SH "SYNOPSIS" .B mcstransd [-f] [-h] .P .SH "DESCRIPTION" This manual page describes the .BR mcstransd program. .P This daemon reads /etc/selinux/{SELINUXTYPE}/setrans.conf configuration file, and communicates with libselinux via a socket in /var/run/setrans. .SH "OPTIONS" .TP \-f Run mcstransd in the foreground. Do not run as a daemon. .TP \-h Output a short summary of available command line options\&. .SH "AUTHOR" This man page was written by Dan Walsh . The program was originally written by Dan Walsh . The program was enhanced/rwwritten by Joe Nall . .SH "FILES" /etc/selinux/{SELINUXTYPE}/setrans.conf .SH "SEE ALSO" .BR mcs (8), policycoreutils-2.3/mcstrans/man/man8/setrans.conf.8000066400000000000000000000064321233221606300225560ustar00rootroot00000000000000.TH "setrans.conf" "8" "13 July 2010" "txtoth@gmail.com" "setrans.conf documentation" .SH "NAME" setrans.conf \- translation configuration file for MCS/MLS SELinux systems .SH "DESCRIPTION" The .I /etc/selinux/{SELINUXTYPE}/setrans.conf configuration file specifies the way that SELinux MCS/MLS labels are translated into human readable form by the mcstransd daemon. The default policies support 16 sensitivity levels (s0 through s15) and 1024 categories (c0 through c1023). Multiple categories can be separated with commas (c0,c1,c3,c5) and a range of categories can be shortened using dot notation (c0.c3,c5). .SS "Keywords" .TP Base\fR once a base is declared, subsequent sensitivity label definitions will have all modifiers applied to them during translation. Sensitivity labels defined before the base declaration are immediately cached and no modifiers will be applied these are used as direct translations. .TP Default\fR defines the category bit range that will be used for inverse bits. .TP Domain\fR creates a new domain with the supplied name. .TP Include\fR read and process the contents of the specified configuration file. .TP Join\fR defines a character used to separate members of a modifier group when more than one is specified (ex. USA/AUS). .TP ModifierGroup\fR a means of grouping category bit definitions by how they modify the sensitivity label. .TP Prefix\fR word(s) that may proceed member(s) of a modifier group (ex. REL USA). .TP Suffix\fR word(s) that may follow member(s) of a modifier group (ex. USA EYES ONLY). .TP Whitespace\fR defines the set of acceptable white space characters that may be used in label being translated. .SS "Sensitivity Level Definition Examples" .TP s0=SystemLow\fR defines a translation of s0 (the lowest sensitivity level) with no categories to SystemLow. .TP s15:c0.c1023=SystemHigh\fR defines a translation of s15:c0.c1023 to SystemHigh. c0.c1023 is shorthand for all categories. A colon separates the sensitivity level and categories. .TP s0\-s15:c0.c1023=SystemLow\-SystemHigh\fR defines a range translation of of s0\-s15:c0.c1023 to SystemLow\-SystemHigh. The two range components are separated by a dash. .TP s0:c0=PatientRecord\fR defines a translation of sensitivity s0 with category c0 to PatientRecord. .TP s0:c1=Accounting\fR defines a translation of sensitivity s0 with category c1 to Accounting. .TP s2:c1,c2,c3=Confidential3Categories .TP s2:c1.c3=Confidential3Categories\fR both define a translation of sensitivity s2 with categories c1, c2 and c3 to Confidential3Categories. .TP s5=TopSecret\fR defines a translation of sensitivity s5 with no categories to TopSecret. .SS "Constraint Examples" .TP c0!c1 if category bits 0 and 1 are both set, the constraint will fail and the original context will be returned. .TP c5.c9>c1 if category bits 5 through 9 are set, bit 1 must also be set or the constraint will fail and the original context will be returned. .TP s1!c5,c9 if category bits 5 and 9 are set and the sensitivity level is s1, the constraint will fail and the original context will be returned. .SH "AUTHOR" Written by Joe Nall . Updated by Ted X. Toth . .SH "SEE ALSO" selinux(8), mcs(8), mls(8), chcon(1) .SH "FILES" /etc/selinux/{SELINUXTYPE}/setrans.conf .br /usr/share/mcstrans/examples policycoreutils-2.3/mcstrans/share/000077500000000000000000000000001233221606300175415ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/000077500000000000000000000000001233221606300213575ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/default/000077500000000000000000000000001233221606300230035ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/default/README000066400000000000000000000002701233221606300236620ustar00rootroot00000000000000Original RHEL 5 setrans.conf To use: cp setrans.conf /etc/selinux/mls/setrans.conf run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlstrans-test default.test policycoreutils-2.3/mcstrans/share/examples/default/default.test000066400000000000000000000013601233221606300253300ustar00rootroot00000000000000SystemLow==s0 SystemHigh==s15:c0.c1023 SystemLow-SystemHigh==s0-s15:c0.c1023 Unclassified==s1 Secret==s2 A==s2:c0 B==s2:c1 SystemLow-Unclassified==s0-s1 Unclassified-Secret==s1-s2 Unclassified-SystemHigh==s1-s15:c0.c1023 SystemLow-Secret==s0-s2 SystemLow-Secret:A==s0-s2:c0 SystemLow-Secret:B==s0-s2:c1 SystemLow-Secret:AB==s0-s2:c0,c1 Unclassified-Secret:A==s1-s2:c0 Unclassified-Secret:B==s1-s2:c1 Unclassified-Secret:AB==s1-s2:c0,c1 Secret-Secret:A==s2-s2:c0 Secret-Secret:B==s2-s2:c1 Secret-Secret:AB==s2-s2:c0,c1 Secret-SystemHigh==s2-s15:c0.c1023 Secret:A-Secret:AB==s2:c0-s2:c0,c1 Secret:A-SystemHigh==s2:c0-s15:c0.c1023 Secret:B-Secret:AB==s2:c1-s2:c0,c1 Secret:B-SystemHigh==s2:c1-s15:c0.c1023 Secret:AB-SystemHigh==s2:c0,c1-s15:c0.c1023 policycoreutils-2.3/mcstrans/share/examples/default/setrans.conf000066400000000000000000000025341233221606300253350ustar00rootroot00000000000000# # Multi-Level Security translation table for SELinux # # Uncomment the following to disable translation libary # disable=1 # # Objects can be labeled with one of 16 levels and be categorized with 0-1023 # categories defined by the admin. # Objects can be in more than one category at a time. # Users can modify this table to translate the MLS labels for different purpose. # # Assumptions: using below MLS labels. # SystemLow # SystemHigh # Unclassified # Secret with compartments A and B. # # SystemLow and SystemHigh s0=SystemLow s15:c0.c1023=SystemHigh s0-s15:c0.c1023=SystemLow-SystemHigh # Unclassified level s1=Unclassified # Secret level with compartments s2=Secret s2:c0=A s2:c1=B # ranges for Unclassified s0-s1=SystemLow-Unclassified s1-s2=Unclassified-Secret s1-s15:c0.c1023=Unclassified-SystemHigh # ranges for Secret with compartments s0-s2=SystemLow-Secret s0-s2:c0=SystemLow-Secret:A s0-s2:c1=SystemLow-Secret:B s0-s2:c0,c1=SystemLow-Secret:AB s1-s2:c0=Unclassified-Secret:A s1-s2:c1=Unclassified-Secret:B s1-s2:c0,c1=Unclassified-Secret:AB s2-s2:c0=Secret-Secret:A s2-s2:c1=Secret-Secret:B s2-s2:c0,c1=Secret-Secret:AB s2-s15:c0.c1023=Secret-SystemHigh s2:c0-s2:c0,c1=Secret:A-Secret:AB s2:c0-s15:c0.c1023=Secret:A-SystemHigh s2:c1-s2:c0,c1=Secret:B-Secret:AB s2:c1-s15:c0.c1023=Secret:B-SystemHigh s2:c0,c1-s15:c0.c1023=Secret:AB-SystemHigh policycoreutils-2.3/mcstrans/share/examples/include/000077500000000000000000000000001233221606300230025ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/include/README000066400000000000000000000004111233221606300236560ustar00rootroot00000000000000Original RHEL 5 setrans.conf pushed into setrans.d as include file To use: cp setrans.conf /etc/selinux/mls/setrans.conf cp setrans.d/* /etc/selinux/mls/setrans.d run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlstrans-test include.test policycoreutils-2.3/mcstrans/share/examples/include/default.test000066400000000000000000000013601233221606300253270ustar00rootroot00000000000000SystemLow==s0 SystemHigh==s15:c0.c1023 SystemLow-SystemHigh==s0-s15:c0.c1023 Unclassified==s1 Secret==s2 A==s2:c0 B==s2:c1 SystemLow-Unclassified==s0-s1 Unclassified-Secret==s1-s2 Unclassified-SystemHigh==s1-s15:c0.c1023 SystemLow-Secret==s0-s2 SystemLow-Secret:A==s0-s2:c0 SystemLow-Secret:B==s0-s2:c1 SystemLow-Secret:AB==s0-s2:c0,c1 Unclassified-Secret:A==s1-s2:c0 Unclassified-Secret:B==s1-s2:c1 Unclassified-Secret:AB==s1-s2:c0,c1 Secret-Secret:A==s2-s2:c0 Secret-Secret:B==s2-s2:c1 Secret-Secret:AB==s2-s2:c0,c1 Secret-SystemHigh==s2-s15:c0.c1023 Secret:A-Secret:AB==s2:c0-s2:c0,c1 Secret:A-SystemHigh==s2:c0-s15:c0.c1023 Secret:B-Secret:AB==s2:c1-s2:c0,c1 Secret:B-SystemHigh==s2:c1-s15:c0.c1023 Secret:AB-SystemHigh==s2:c0,c1-s15:c0.c1023 policycoreutils-2.3/mcstrans/share/examples/include/setrans.conf000066400000000000000000000007561233221606300253400ustar00rootroot00000000000000# # Multi-Level Security translation table for SELinux # # Uncomment the following to disable translation libary # disable=1 # # Objects can be labeled with one of 16 levels and be categorized with 0-1023 # categories defined by the admin. # Objects can be in more than one category at a time. # Users can modify this table to translate the MLS labels for different purpose. # # Demonstrate Include by moving everthing to an include file # Include=/etc/selinux/mls/setrans.d/include-example policycoreutils-2.3/mcstrans/share/examples/include/setrans.d/000077500000000000000000000000001233221606300247035ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/include/setrans.d/include-example000066400000000000000000000025341233221606300277060ustar00rootroot00000000000000# # Multi-Level Security translation table for SELinux # # Uncomment the following to disable translation libary # disable=1 # # Objects can be labeled with one of 16 levels and be categorized with 0-1023 # categories defined by the admin. # Objects can be in more than one category at a time. # Users can modify this table to translate the MLS labels for different purpose. # # Assumptions: using below MLS labels. # SystemLow # SystemHigh # Unclassified # Secret with compartments A and B. # # SystemLow and SystemHigh s0=SystemLow s15:c0.c1023=SystemHigh s0-s15:c0.c1023=SystemLow-SystemHigh # Unclassified level s1=Unclassified # Secret level with compartments s2=Secret s2:c0=A s2:c1=B # ranges for Unclassified s0-s1=SystemLow-Unclassified s1-s2=Unclassified-Secret s1-s15:c0.c1023=Unclassified-SystemHigh # ranges for Secret with compartments s0-s2=SystemLow-Secret s0-s2:c0=SystemLow-Secret:A s0-s2:c1=SystemLow-Secret:B s0-s2:c0,c1=SystemLow-Secret:AB s1-s2:c0=Unclassified-Secret:A s1-s2:c1=Unclassified-Secret:B s1-s2:c0,c1=Unclassified-Secret:AB s2-s2:c0=Secret-Secret:A s2-s2:c1=Secret-Secret:B s2-s2:c0,c1=Secret-Secret:AB s2-s15:c0.c1023=Secret-SystemHigh s2:c0-s2:c0,c1=Secret:A-Secret:AB s2:c0-s15:c0.c1023=Secret:A-SystemHigh s2:c1-s2:c0,c1=Secret:B-Secret:AB s2:c1-s15:c0.c1023=Secret:B-SystemHigh s2:c0,c1-s15:c0.c1023=Secret:AB-SystemHigh policycoreutils-2.3/mcstrans/share/examples/nato/000077500000000000000000000000001233221606300223205ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/nato/README000066400000000000000000000005441233221606300232030ustar00rootroot00000000000000NATO example test setrans.conf To use: mkdir /etc/selinux/mls/mcstrand.d cp rel.conf /etc/selinux/mls/mcstrand.d cp eyes-only.conf /etc/selinux/mls/mcstrand.d cp constraints.conf /etc/selinux/mls/mcstrand.d cp setrans.conf /etc/selinux/mls/setrans.conf sudo run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlstrans-test nato.test policycoreutils-2.3/mcstrans/share/examples/nato/nato.test000066400000000000000000000016131233221606300241630ustar00rootroot00000000000000NATO CONFIDENTIAL==s4:c1,c200.c511 CONFIDENTIAL-NATO SECRET!=s4:c0,c2,c11,c200.c511-s5:c1,c200.c511 NATO SECRET REL NATO==s5:c1,c201.c204,c206.c218,c220.c222,c224.c238,c240.c256,c259,c260,c262.c267,c270.c273,c275.c277,c279.c287,c289.c297,c299,c301.c307,c309,c311.c330,c334.c364,c367.c377,c379,c380,c382.c386,c388.c405,c408.c422,c424.c429,c431.c511 NATO CONFIDENTIAL NATO EYES ONLY==s4:c1,c200.c204,c206.c218,c220.c222,c224.c238,c240.c256,c259,c260,c262.c267,c270.c273,c275.c277,c279.c287,c289.c297,c299,c301.c307,c309,c311.c330,c334.c364,c367.c377,c379,c380,c382.c386,c388.c405,c408.c422,c424.c429,c431.c511 NATO CONFIDENTIAL-NATO SECRET==s4:c1,c200.c511-s5:c1,c200.c511 NATO CONFIDENTIAL REL AUS/US-NATO SECRET REL AUS/US==s4:c1,c201.c214,c216.c429,c431.c511-s5:c1,c201.c214,c216.c429,c431.c511 NATO CONFIDENTIAL DEU EYES ONLY-NATO SECRET DEU EYES ONLY==s4:c1,c200.c257,c259.c511-s5:c1,c200.c257,c259.c511 policycoreutils-2.3/mcstrans/share/examples/nato/setrans.conf000066400000000000000000000010241233221606300246430ustar00rootroot00000000000000# UNCLASSIFIED Domain=NATOEXAMPLE s0=SystemLow s15:c0.c1023=SystemHigh s0-s15:c0.c1023=SystemLow-SystemHigh Base=Sensitivity Levels s1=UNCLASSIFIED s3:c0,c2,c11,c200.c511=RESTRICTED s4:c0,c2,c11,c200.c511=CONFIDENTIAL s5:c0,c2,c11,c200.c511=SECRET s1:c1=NATO UNCLASSIFIED s3:c1,c200.c511=NATO RESTRICTED s4:c1,c200.c511=NATO CONFIDENTIAL s5:c1,c200.c511=NATO SECRET Include=/etc/selinux/mls/setrans.d/rel.conf Include=/etc/selinux/mls/setrans.d/eyes-only.conf Include=/etc/selinux/mls/setrans.d/constraints.conf # UNCLASSIFIED policycoreutils-2.3/mcstrans/share/examples/nato/setrans.d/000077500000000000000000000000001233221606300242215ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/nato/setrans.d/constraints.conf000066400000000000000000000002471233221606300274420ustar00rootroot00000000000000# UNCLASSIFIED # These constraints apply to computed translations, # not cached or preset translations. # # nato and non-nato are incompatible c0!c1 #UNCLASSIFIED policycoreutils-2.3/mcstrans/share/examples/nato/setrans.d/eyes-only.conf000066400000000000000000000410771233221606300270250ustar00rootroot00000000000000#UNCLASSIFIED ModifierGroup=Eyes Only Whitespace=- ,/ Join=/ Suffix=EYES ONLY Default=c200.c511 ~c205,~c219,~c223,~c239,~c257,~c258,~c261,~c268,~c269,~c274,~c278,~c288,~c298,~c300,~c308,~c310,~c331,~c332,~c333,~c365,~c366,~c378,~c381,~c387,~c406,~c407,~c423,~c430=NATO # Aruba - bit 201 ~c201=AA # Aruba ~c201=ABW # Aruba # Antigua and Barbuda - bit 214 ~c214=AC # Antigua and Barbuda ~c214=ATG # Antigua and Barbuda # United Arab Emirates - bit 208 #~c208=AE # United Arab Emirates ~c208=ARE # United Arab Emirates # Afghanistan - bit 202 ~c202=AF # Afghanistan ~c202=AFG # Afghanistan # Algeria - bit 263 ~c263=AG # Algeria ~c263=DZA # Algeria # Azerbaijan - bit 217 ~c217=AJ # Azerbaijan ~c217=AZE # Azerbaijan # Albania - bit 205 ~c205=AL # Albania ~c205=ALB # Albania # Armenia - bit 210 ~c210=AM # Armenia ~c210=ARM # Armenia # Andorra - bit 206 ~c206=AN # Andorra ~c206=AND # Andorra # Angola - bit 203 ~c203=AO # Angola ~c203=AGO # Angola # American Samoa - bit 211 ~c211=AQ # American Samoa ~c211=ASM # American Samoa # Argentina - bit 209 ~c209=AR # Argentina ~c209=ARG # Argentina # Australia - bit 215 ~c215=AUS # Australia ~c215=AS # Australia # Austria - bit 216 ~c216=AU # Austria ~c216=AUT # Austria # Anguilla - bit 204 ~c204=AV # Anguilla ~c204=AIA # Anguilla # Antarctica - bit 212 ~c212=AY # Antarctica ~c212=ATA # Antarctica # Bahrain - bit 224 ~c224=BA # Bahrain ~c224=BHR # Bahrain # Barbados - bit 233 ~c233=BB # Barbados ~c233=BRB # Barbados # Botswana - bit 237 ~c237=BC # Botswana ~c237=BWA # Botswana # Bermuda - bit 230 ~c230=BD # Bermuda ~c230=BMU # Bermuda # Belgium - bit 219 ~c219=BE # Belgium ~c219=BEL # Belgium # Bahamas, The - bit 225 ~c225=BF # Bahamas, The ~c225=BHS # Bahamas, The # Bangladesh - bit 222 ~c222=BG # Bangladesh ~c222=BGD # Bangladesh # Belize - bit 229 ~c229=BH # Belize ~c229=BLZ # Belize # Bosnia and Herzegovina - bit 226 ~c226=BK # Bosnia and Herzegovina ~c226=BIH # Bosnia and Herzegovina # Bolivia - bit 231 ~c231=BL # Bolivia ~c231=BOL # Bolivia # Burma - bit 346 ~c346=BM # Burma ~c346=MMR # Burma # Benin - bit 220 ~c220=BN # Benin ~c220=BEN # Benin # Belarus - bit 228 ~c228=BO # Belarus ~c228=BLR # Belarus # Solomon Islands - bit 397 ~c397=BP # Solomon Islands ~c397=SLB # Solomon Islands # Brazil - bit 232 ~c232=BR # Brazil ~c232=BRA # Brazil # Bhutan - bit 235 ~c235=BT # Bhutan ~c235=BTN # Bhutan # Bulgaria - bit 223 ~c223=BU # Bulgaria ~c223=BGR # Bulgaria # Bouvet Island - bit 236 ~c236=BV # Bouvet Island ~c236=BVT # Bouvet Island # Brunei - bit 234 ~c234=BX # Brunei ~c234=BRN # Brunei # Burundi - bit 218 ~c218=BY # Burundi ~c218=BDI # Burundi # Canada - bit 239 ~c239=CA # Canada ~c239=CAN # Canada # Cambodia - bit 318 ~c318=CB # Cambodia ~c318=KHM # Cambodia # Chad - bit 413 ~c413=CD # Chad ~c413=TCD # Chad # Sri Lanka - bit 329 ~c329=CE # Sri Lanka ~c329=LKA # Sri Lanka # Congo, Republic of the - bit 247 ~c247=CF # Congo, Republic of the ~c247=COG # Congo, Republic of the # Congo, Democratic Republic of the - bit 246 ~c246=CG # Congo, Democratic Republic of the ~c246=COD # Congo, Democratic Republic of the # China - bit 243 ~c243=CH # China ~c243=CHN # China # Chile - bit 242 ~c242=CI # Chile ~c242=CHL # Chile # Cayman Islands - bit 255 ~c255=CJ # Cayman Islands ~c255=CYM # Cayman Islands # Cocos (Keeling) Islands - bit 240 part of AUS ~c240=CK # Cocos (Keeling) Islands ~c240=CCK # Cocos (Keeling) Islands # Cameroon - bit 245 ~c245=CM # Cameroon ~c245=CMR # Cameroon # Comoros - bit 250 ~c250=CN # Comoros ~c250=COM # Comoros # Colombia - bit 249 ~c249=CO # Colombia ~c249=COL # Colombia # Northern Mariana Islands - bit 349 ~c349=CQ # Northern Mariana Islands ~c349=MNP # Northern Mariana Islands # Costa Rica - bit 252 ~c252=CS # Costa Rica ~c252=CRI # Costa Rica # Central African Republic - bit 238 ~c238=CT # Central African Republic ~c238=CAF # Central African Republic # Cuba - bit 253 ~c253=CU # Cuba ~c253=CUB # Cuba # Cape Verde - bit 251 ~c251=CV # Cape Verde ~c251=CPV # Cape Verde # Cook Islands - bit 248 ~c248=CW # Cook Islands ~c248=COK # Cook Islands # Cyprus - bit 256 ~c256=CY # Cyprus ~c256=CYP # Cyprus # Denmark - bit 261 ~c261=DA # Denmark ~c261=DNK # Denmark # Djibouti - bit 259 ~c259=DJ # Djibouti ~c259=DJI # Djibouti # Dominica - bit 260 ~c260=DO # Dominica ~c260=DMA # Dominica # Dominican Republic - bit 262 ~c262=DR # Dominican Republic ~c262=DOM # Dominican Republic # Ecuador - bit 264 ~c264=EC # Ecuador ~c264=ECU # Ecuador # Egypt - bit 265 ~c265=EG # Egypt ~c265=EGY # Egypt # Ireland - bit 305 ~c305=EI # Ireland ~c305=IRL # Ireland # Equatorial Guinea - bit 287 ~c287=EK # Equatorial Guinea ~c287=GNQ # Equatorial Guinea # Estonia - bit 269 ~c269=EN # Estonia ~c269=EST # Estonia # Eritrea - bit 266 ~c266=ER # Eritrea ~c266=ERI # Eritrea # El Salvador - bit 399 ~c399=ES # El Salvador ~c399=SLV # El Salvador # Ethiopia - bit 270 ~c270=ET # Ethiopia ~c270=ETH # Ethiopia # Czech Republic - bit 257 #~c257=EZ # Czech Republic ~c257=CZE # Czech Republic # French Guiana - bit 292 ~c292=FG # French Guiana ~c292=GUF # French Guiana # Finland - bit 271 ~c271=FI # Finland ~c271=FIN # Finland # Fiji - bit 272 ~c272=FJ # Fiji ~c272=FJI # Fiji # Falkland Islands (Islas Malvinas) - bit 273 ~c273=FK # Falkland Islands (Islas Malvinas) ~c273=FLK # Falkland Islands (Islas Malvinas) # Micronesia, Federated States of - bit 276 ~c276=FM # Micronesia, Federated States of ~c276=FSM # Micronesia, Federated States of # Faroe Islands - bit 275 ~c275=FO # Faroe Islands ~c275=FRO # Faroe Islands # French Polynesia - bit 384 ~c384=FP # French Polynesia ~c384=PYF # French Polynesia # France - bit 274 ~c274=FR # France ~c274=FRA # France # French Southern and Antarctic Lands - bit 213 ~c213=FS # French Southern and Antarctic Lands ~c213=ATF # French Southern and Antarctic Lands # Gambia, The - bit 285 ~c285=GA # Gambia, The ~c285=GMB # Gambia, The # Gabon - bit 277 ~c277=GB # Gabon ~c277=GAB # Gabon # Georgia - bit 279 ~c279=GG # Georgia ~c279=GEO # Georgia # Ghana - bit 281 ~c281=GH # Ghana ~c281=GHA # Ghana # Gibraltar - bit 282 ~c282=GI # Gibraltar ~c282=GIB # Gibraltar # Grenada - bit 289 ~c289=GJ # Grenada ~c289=GRD # Grenada # Guernsey - bit 280 part of UK ~c280=GK # Guernsey ~c280=GGY # Guernsey # Greenland - bit 290 ~c290=GL # Greenland ~c290=GRL # Greenland # Germany - bit 258 #~c258=GM # Germany ~c258=DEU # Germany # Guadeloupe - bit 284 ~c284=GP # Guadeloupe ~c284=GLP # Guadeloupe # Guam - bit 293 ~c293=GQ # Guam ~c293=GUM # Guam # Greece - bit 288 ~c288=GR # Greece ~c288=GRC # Greece # Guatemala - bit 291 ~c291=GT # Guatemala ~c291=GTM # Guatemala # Guinea - bit 283 ~c283=GV # Guinea ~c283=GIN # Guinea # Guyana - bit 294 ~c294=GY # Guyana ~c294=GUY # Guyana # Gaza Strip - bit 383 #~c383=GZ # Gaza Strip ~c383=PSE # Gaza Strip # Haiti - bit 299 ~c299=HA # Haiti ~c299=HTI # Haiti # Hong Kong - bit 295 ~c295=HK # Hong Kong ~c295=HKG # Hong Kong # Heard Island and McDonald Islands - bit 296 ~c296=HM # Heard Island and McDonald Islands ~c296=HMD # Heard Island and McDonald Islands # Honduras - bit 297 ~c297=HO # Honduras ~c297=HND # Honduras # Croatia - bit 298 ~c298=HR # Croatia ~c298=HRV # Croatia # Hungary - bit 300 ~c300=HU # Hungary ~c300=HUN # Hungary # Iceland - bit 308 ~c308=IC # Iceland ~c308=ISL # Iceland # Indonesia - bit 301 ~c301=ID # Indonesia ~c301=IDN # Indonesia # Isle of Man - bit 302 part of UK ~c302=IM # Isle of Man ~c302=IMN # Isle of Man # India - bit 303 ~c303=IN # India ~c303=IND # India # British Indian Ocean Territory - bit 304 ~c304=IO # British Indian Ocean Territory ~c304=IOT # British Indian Ocean Territory # Iran - bit 306 ~c306=IR # Iran ~c306=IRN # Iran # Israel - bit 309 ~c309=IS # Israel ~c309=ISR # Israel # Italy - bit 310 ~c310=IT # Italy ~c310=ITA # Italy # Cote d'Ivoire - bit 244 ~c244=IV # Cote d'Ivoire ~c244=CIV # Cote d'Ivoire # Iraq - bit 307 ~c307=IZ # Iraq ~c307=IRQ # Iraq # Japan - bit 314 ~c314=JA # Japan ~c314=JPN # Japan # Jersey - bit 312 part of UK ~c312=JE # Jersey ~c312=JEY # Jersey # Jamaica - bit 311 ~c311=JM # Jamaica ~c311=JAM # Jamaica # Jordan - bit 313 ~c313=JO # Jordan ~c313=JOR # Jordan # Kenya - bit 316 ~c316=KE # Kenya ~c316=KEN # Kenya # Kyrgyzstan - bit 317 ~c317=KG # Kyrgyzstan ~c317=KGZ # Kyrgyzstan # Korea, North - bit 380 ~c380=KN # Korea, North ~c380=PRK # Korea, North # Kiribati - bit 319 ~c319=KR # Kiribati ~c319=KIR # Kiribati # Korea, South - bit 321 ~c321=KS # Korea, South ~c321=ROK # Korea, South # Christmas Island - bit 254 ~c254=KT # Christmas Island ~c254=CXR # Christmas Island # Kuwait - bit 322 ~c322=KU # Kuwait ~c322=KWT # Kuwait # Kazakhstan - bit 315 ~c315=KZ # Kazakhstan ~c315=KAZ # Kazakhstan # Laos - bit 323 ~c323=LA # Laos ~c323=LAO # Laos # Lebanon - bit 324 ~c324=LE # Lebanon ~c324=LBN # Lebanon # Latvia - bit 333 ~c333=LG # Latvia ~c333=LVA # Latvia # Lithuania - bit 331 ~c331=LH # Lithuania ~c331=LTU # Lithuania # Liberia - bit 325 ~c325=LI # Liberia ~c325=LBR # Liberia # Slovakia - bit 406 ~c406=LO # Slovakia ~c406=SVK # Slovakia # Liechtenstein - bit 328 ~c328=LS # Liechtenstein ~c328=LIE # Liechtenstein # Lesotho - bit 330 ~c330=LT # Lesotho ~c330=LSO # Lesotho # Luxembourg - bit 332 ~c332=LU # Luxembourg ~c332=LUX # Luxembourg # Libya - bit 326 ~c326=LY # Libya ~c326=LBY # Libya # Madagascar - bit 339 ~c339=MA # Madagascar ~c339=MDG # Madagascar # Martinique - bit 353 ~c353=MB # Martinique ~c353=MTQ # Martinique # Macau - bit 334 ~c334=MC # Macau ~c334=MAC # Macau # Moldova - bit 338 ~c338=MD # Moldova ~c338=MDA # Moldova # Mayotte - bit 357 part of FRA ~c357=MF # Mayotte ~c357=MYT # Mayotte # Mongolia - bit 348 ~c348=MG # Mongolia ~c348=MNG # Mongolia # Montserrat - bit 352 ~c352=MH # Montserrat ~c352=MSR # Montserrat # Malawi - bit 355 ~c355=MI # Malawi ~c355=MWI # Malawi # Montenegro - bit 347 ~c347=MJ # Montenegro ~c347=MNE # Montenegro # Macedonia - bit 343 part of FYR ~c343=MK # Macedonia ~c343=MKD # Macedonia # Mali - bit 344 ~c344=ML # Mali ~c344=MLI # Mali # Monaco - bit 337 ~c337=MN # Monaco ~c337=MCO # Monaco # Morocco - bit 336 ~c336=MO # Morocco ~c336=MAR # Morocco # Mauritius - bit 354 ~c354=MP # Mauritius ~c354=MUS # Mauritius # Mauritania - bit 351 ~c351=MR # Mauritania ~c351=MRT # Mauritania # Malta - bit 345 ~c345=MT # Malta ~c345=MLT # Malta # Oman - bit 370 ~c370=MU # Oman ~c370=OMN # Oman # Maldives - bit 340 ~c340=MV # Maldives ~c340=MDV # Maldives # Mexico - bit 341 ~c341=MX # Mexico ~c341=MEX # Mexico # Malaysia - bit 356 ~c356=MY # Malaysia ~c356=MYS # Malaysia # Mozambique - bit 350 ~c350=MZ # Mozambique ~c350=MOZ # Mozambique # New Caledonia - bit 359 ~c359=NC # New Caledonia ~c359=NCL # New Caledonia # Niue - bit 364 ~c364=NE # Niue ~c364=NIU # Niue # Norfolk Island - bit 361 ~c361=NF # Norfolk Island ~c361=NFK # Norfolk Island # Niger - bit 360 ~c360=NG # Niger ~c360=NER # Niger # Vanuatu - bit 438 ~c438=NH # Vanuatu ~c438=VUT # Vanuatu # Nigeria - bit 362 ~c362=NI # Nigeria ~c362=NGA # Nigeria # Netherlands - bit 365 ~c365=NL # Netherlands ~c365=NLD # Netherlands # Norway - bit 366 ~c366=NO # Norway ~c366=NOR # Norway # Nepal - bit 367 ~c367=NP # Nepal ~c367=NPL # Nepal # Nauru - bit 368 ~c368=NR # Nauru ~c368=NRU # Nauru # Suriname - bit 405 ~c405=NS # Suriname ~c405=SUR # Suriname # Netherlands Antilles - bit 207 ~c207=NT # Netherlands Antilles ~c207=ANT # Netherlands Antilles # Nicaragua - bit 363 ~c363=NU # Nicaragua ~c363=NIC # Nicaragua # New Zealand - bit 369 ~c369=NZ # New Zealand ~c369=NZL # New Zealand # Paraguay - bit 382 ~c382=PA # Paraguay ~c382=PRY # Paraguay # Pitcairn Islands - bit 373 ~c373=PC # Pitcairn Islands ~c373=PCN # Pitcairn Islands # Peru - bit 374 ~c374=PE # Peru ~c374=PER # Peru # Pakistan - bit 371 ~c371=PK # Pakistan ~c371=PAK # Pakistan # Poland - bit 378 ~c378=PL # Poland ~c378=POL # Poland # Panama - bit 372 ~c372=PM # Panama ~c372=PAN # Panama # Portugal - bit 381 ~c381=PO # Portugal ~c381=PRT # Portugal # Papua New Guinea - bit 377 ~c377=PP # Papua New Guinea ~c377=PNG # Papua New Guinea # Palau - bit 376 #~c376=PS # Palau ~c376=PLW # Palau # Guinea-Bissau - bit 286 ~c286=PU # Guinea-Bissau ~c286=GNB # Guinea-Bissau # Qatar - bit 385 ~c385=QA # Qatar ~c385=QAT # Qatar # Serbia - bit 403 #~c403=RB # Serbia ~c403=SRB # Serbia # Reunion - bit 386 ~c386=RE # Reunion ~c386=REU # Reunion # Marshall Islands - bit 342 ~c342=RM # Marshall Islands ~c342=MHL # Marshall Islands # Saint Martin - bit 335 ~c335=RN # Saint Martin ~c335=MAF # Saint Martin # Romania - bit 387 ~c387=RO # Romania ~c387=ROU # Romania # Philippines - bit 375 ~c375=RP # Philippines ~c375=PHL # Philippines # Puerto Rico - bit 379 ~c379=RQ # Puerto Rico ~c379=PRI # Puerto Rico # Russia - bit 388 #~c388=RS # Russia ~c388=RUS # Russia # Rwanda - bit 389 ~c389=RW # Rwanda ~c389=RWA # Rwanda # Saudi Arabia - bit 390 ~c390=SA # Saudi Arabia ~c390=SAU # Saudi Arabia # Saint Pierre and Miquelon - bit 402 ~c402=SB # Saint Pierre and Miquelon ~c402=SPM # Saint Pierre and Miquelon # Saint Kitts and Nevis - bit 320 ~c320=SC # Saint Kitts and Nevis ~c320=KNA # Saint Kitts and Nevis # Seychelles - bit 410 ~c410=SE # Seychelles ~c410=SYC # Seychelles # South Africa - bit 442 ~c442=SF # South Africa ~c442=ZAF # South Africa # Senegal - bit 392 ~c392=SG # Senegal ~c392=SEN # Senegal # Saint Helena - bit 395 ~c395=SH # Saint Helena ~c395=SHN # Saint Helena # Slovenia - bit 407 #~c407=SI # Slovenia ~c407=SVN # Slovenia # Sierra Leone - bit 398 ~c398=SL # Sierra Leone ~c398=SLE # Sierra Leone # San Marino - bit 400 ~c400=SM # San Marino ~c400=SMR # San Marino # Singapore - bit 393 ~c393=SN # Singapore ~c393=SGP # Singapore # Somalia - bit 401 ~c401=SO # Somalia ~c401=SOM # Somalia # Spain - bit 268 #~c268=SP # Spain ~c268=ESP # Spain # Saint Lucia - bit 327 ~c327=ST # Saint Lucia ~c327=LCA # Saint Lucia # Sudan - bit 391 ~c391=SU # Sudan ~c391=SDN # Sudan # Svalbard - bit 396 #~c396=SV # Svalbard ~c396=SJM # Svalbard # Sweden - bit 408 ~c408=SW # Sweden ~c408=SWE # Sweden # South Georgia and the Islands - bit 394 ~c394=SX # South Georgia and the Islands ~c394=SGS # South Georgia and the Islands # Syria - bit 411 ~c411=SY # Syria ~c411=SYR # Syria # Switzerland - bit 241 ~c241=SZ # Switzerland ~c241=CHE # Switzerland # Saint Barthelemy - bit 227 ~c227=TB # Saint Barthelemy ~c227=BLM # Saint Barthelemy # Trinidad and Tobago - bit 421 ~c421=TD # Trinidad and Tobago ~c421=TTO # Trinidad and Tobago # Thailand - bit 415 ~c415=TH # Thailand ~c415=THA # Thailand # Tajikistan - bit 416 ~c416=TI # Tajikistan ~c416=TJK # Tajikistan # Turks and Caicos Islands - bit 412 ~c412=TK # Turks and Caicos Islands ~c412=TCA # Turks and Caicos Islands # Togo - bit 414 ~c414=TGO # Tokelau - bit 417 ~c417=TL # Tokelau ~c417=TKL # Tokelau # Tonga - bit 420 ~c420=TN # Tonga ~c420=TON # Tonga # Togo - bit 414 ~c414=TO # Togo ~c414=TGO # Togo # Sao Tome and Principe - bit 404 ~c404=TP # Sao Tome and Principe ~c404=STP # Sao Tome and Principe # Tunisia - bit 422 ~c422=TS # Tunisia ~c422=TUN # Tunisia # Timor-Leste - bit 419 ~c419=TT # Timor-Leste ~c419=TLS # Timor-Leste # Turkey - bit 423 ~c423=TU # Turkey ~c423=TUR # Turkey # Tuvalu - bit 424 ~c424=TV # Tuvalu ~c424=TUV # Tuvalu # Taiwan - bit 425 ~c425=TW # Taiwan ~c425=TWN # Taiwan # Turkmenistan - bit 418 ~c418=TX # Turkmenistan ~c418=TKM # Turkmenistan # Tanzania - bit 426 ~c426=TZ # Tanzania ~c426=TZA # Tanzania # Uganda - bit 427 ~c427=UG # Uganda ~c427=UGA # Uganda # United Kingdom - bit 278 ~c278=UK # United Kingdom ~c278=GBR # United Kingdom # Ukraine - bit 428 ~c428=UP # Ukraine ~c428=UKR # Ukraine # United States - bit 430 ~c430=US # United States ~c430=USA # United States # Burkina Faso - bit 221 ~c221=UV # Burkina Faso ~c221=BFA # Burkina Faso # Uruguay - bit 429 ~c429=UY # Uruguay ~c429=URY # Uruguay # Uzbekistan - bit 431 ~c431=UZ # Uzbekistan ~c431=UZB # Uzbekistan # Saint Vincent and the Grenadines - bit 433 ~c433=VC # Saint Vincent and the Grenadines ~c433=VCT # Saint Vincent and the Grenadines # Venezuela - bit 434 ~c434=VE # Venezuela ~c434=VEN # Venezuela # British Virgin Islands - bit 435 ~c435=VI # British Virgin Islands ~c435=VGB # British Virgin Islands # Vietnam - bit 437 ~c437=VM # Vietnam ~c437=VNM # Vietnam # Virgin Islands - bit 436 #~c436=VQ # Virgin Islands ~c436=VIR # Virgin Islands # Holy See (Vatican City) - bit 432 ~c432=VT # Holy See (Vatican City) ~c432=VAT # Holy See (Vatican City) # Namibia - bit 358 ~c358=WA # Namibia ~c358=NAM # Namibia # West Bank - bit 383 ~c383=WE # West Bank # Wallis and Futuna - bit 439 ~c439=WF # Wallis and Futuna ~c439=WLF # Wallis and Futuna # Western Sahara - bit 267 ~c267=WI # Western Sahara ~c267=ESH # Western Sahara # Samoa - bit 440 #~c440=WS # Samoa ~c440=WSM # Samoa # Swaziland - bit 409 ~c409=WZ # Swaziland ~c409=SWZ # Swaziland # Yemen - bit 441 #~c441=YM # Yemen ~c441=YEM # Yemen # Zambia - bit 443 ~c443=ZA # Zambia ~c443=ZMB # Zambia # Zimbabwe - bit 444 ~c444=ZI # Zimbabwe ~c444=ZWE # Zimbabwe #UNCLASSIFIED policycoreutils-2.3/mcstrans/share/examples/nato/setrans.d/rel.conf000066400000000000000000000467261233221606300256710ustar00rootroot00000000000000#UNCLASSIFIED ModifierGroup=Releasable To Whitespace=- ,/ Join=/ Prefix=REL Prefix=REL TO Prefix=RELEASABLE TO Prefix=RELEASEABLE TO Default=c200.c511 ~c200.c511=EVERBODY ~c200,~c205,~c219,~c223,~c239,~c257,~c258,~c261,~c268,~c269,~c274,~c278,~c288,~c298,~c300,~c308,~c310,~c331,~c332,~c333,~c365,~c366,~c378,~c381,~c387,~c406,~c407,~c423,~c430=NATO # Aruba - bit 201 ~c200,~c201=AA # Aruba ~c200,~c201=ABW # Aruba # Antigua and Barbuda - bit 214 ~c200,~c214=AC # Antigua and Barbuda ~c200,~c214=ATG # Antigua and Barbuda # United Arab Emirates - bit 208 #~c200,~c208=AE # United Arab Emirates ~c200,~c208=ARE # United Arab Emirates # Afghanistan - bit 202 ~c200,~c202=AF # Afghanistan ~c200,~c202=AFG # Afghanistan # Algeria - bit 263 ~c200,~c263=AG # Algeria ~c200,~c263=DZA # Algeria # Azerbaijan - bit 217 ~c200,~c217=AJ # Azerbaijan ~c200,~c217=AZE # Azerbaijan # Albania - bit 205 ~c200,~c205=AL # Albania ~c200,~c205=ALB # Albania # Armenia - bit 210 ~c200,~c210=AM # Armenia ~c200,~c210=ARM # Armenia # Andorra - bit 206 ~c200,~c206=AN # Andorra ~c200,~c206=AND # Andorra # Angola - bit 203 ~c200,~c203=AO # Angola ~c200,~c203=AGO # Angola # American Samoa - bit 211 ~c200,~c211=AQ # American Samoa ~c200,~c211=ASM # American Samoa # Argentina - bit 209 ~c200,~c209=AR # Argentina ~c200,~c209=ARG # Argentina # Australia - bit 215 ~c200,~c215=AUS # Australia ~c200,~c215=AS # Australia # Austria - bit 216 ~c200,~c216=AU # Austria ~c200,~c216=AUT # Austria # Anguilla - bit 204 ~c200,~c204=AV # Anguilla ~c200,~c204=AIA # Anguilla # Antarctica - bit 212 ~c200,~c212=AY # Antarctica ~c200,~c212=ATA # Antarctica # Bahrain - bit 224 ~c200,~c224=BA # Bahrain ~c200,~c224=BHR # Bahrain # Barbados - bit 233 ~c200,~c233=BB # Barbados ~c200,~c233=BRB # Barbados # Botswana - bit 237 ~c200,~c237=BC # Botswana ~c200,~c237=BWA # Botswana # Bermuda - bit 230 ~c200,~c230=BD # Bermuda ~c200,~c230=BMU # Bermuda # Belgium - bit 219 ~c200,~c219=BE # Belgium ~c200,~c219=BEL # Belgium # Bahamas, The - bit 225 ~c200,~c225=BF # Bahamas, The ~c200,~c225=BHS # Bahamas, The # Bangladesh - bit 222 ~c200,~c222=BG # Bangladesh ~c200,~c222=BGD # Bangladesh # Belize - bit 229 ~c200,~c229=BH # Belize ~c200,~c229=BLZ # Belize # Bosnia and Herzegovina - bit 226 ~c200,~c226=BK # Bosnia and Herzegovina ~c200,~c226=BIH # Bosnia and Herzegovina # Bolivia - bit 231 ~c200,~c231=BL # Bolivia ~c200,~c231=BOL # Bolivia # Burma - bit 346 ~c200,~c346=BM # Burma ~c200,~c346=MMR # Burma # Benin - bit 220 ~c200,~c220=BN # Benin ~c200,~c220=BEN # Benin # Belarus - bit 228 ~c200,~c228=BO # Belarus ~c200,~c228=BLR # Belarus # Solomon Islands - bit 397 ~c200,~c397=BP # Solomon Islands ~c200,~c397=SLB # Solomon Islands # Brazil - bit 232 ~c200,~c232=BR # Brazil ~c200,~c232=BRA # Brazil # Bhutan - bit 235 ~c200,~c235=BT # Bhutan ~c200,~c235=BTN # Bhutan # Bulgaria - bit 223 ~c200,~c223=BU # Bulgaria ~c200,~c223=BGR # Bulgaria # Bouvet Island - bit 236 ~c200,~c236=BV # Bouvet Island ~c200,~c236=BVT # Bouvet Island # Brunei - bit 234 ~c200,~c234=BX # Brunei ~c200,~c234=BRN # Brunei # Burundi - bit 218 ~c200,~c218=BY # Burundi ~c200,~c218=BDI # Burundi # Canada - bit 239 ~c200,~c239=CAN # Canada ~c200,~c239=CA # Canada # Cambodia - bit 318 ~c200,~c318=CB # Cambodia ~c200,~c318=KHM # Cambodia # Chad - bit 413 ~c200,~c413=CD # Chad ~c200,~c413=TCD # Chad # Sri Lanka - bit 329 ~c200,~c329=CE # Sri Lanka ~c200,~c329=LKA # Sri Lanka # Congo, Republic of the - bit 247 ~c200,~c247=CF # Congo, Republic of the ~c200,~c247=COG # Congo, Republic of the # Congo, Democratic Republic of the - bit 246 ~c200,~c246=CG # Congo, Democratic Republic of the ~c200,~c246=COD # Congo, Democratic Republic of the # China - bit 243 ~c200,~c243=CH # China ~c200,~c243=CHN # China # Chile - bit 242 ~c200,~c242=CI # Chile ~c200,~c242=CHL # Chile # Cayman Islands - bit 255 ~c200,~c255=CJ # Cayman Islands ~c200,~c255=CYM # Cayman Islands # Cocos (Keeling) Islands - bit 240 part of AUS ~c200,~c240=CK # Cocos (Keeling) Islands ~c200,~c240=CCK # Cocos (Keeling) Islands # Cameroon - bit 245 ~c200,~c245=CM # Cameroon ~c200,~c245=CMR # Cameroon # Comoros - bit 250 ~c200,~c250=CN # Comoros ~c200,~c250=COM # Comoros # Colombia - bit 249 ~c200,~c249=CO # Colombia ~c200,~c249=COL # Colombia # Northern Mariana Islands - bit 349 ~c200,~c349=CQ # Northern Mariana Islands ~c200,~c349=MNP # Northern Mariana Islands # Costa Rica - bit 252 ~c200,~c252=CS # Costa Rica ~c200,~c252=CRI # Costa Rica # Central African Republic - bit 238 ~c200,~c238=CT # Central African Republic ~c200,~c238=CAF # Central African Republic # Cuba - bit 253 ~c200,~c253=CU # Cuba ~c200,~c253=CUB # Cuba # Cape Verde - bit 251 ~c200,~c251=CV # Cape Verde ~c200,~c251=CPV # Cape Verde # Cook Islands - bit 248 ~c200,~c248=CW # Cook Islands ~c200,~c248=COK # Cook Islands # Cyprus - bit 256 ~c200,~c256=CY # Cyprus ~c200,~c256=CYP # Cyprus # Denmark - bit 261 ~c200,~c261=DA # Denmark ~c200,~c261=DNK # Denmark # Djibouti - bit 259 ~c200,~c259=DJ # Djibouti ~c200,~c259=DJI # Djibouti # Dominica - bit 260 ~c200,~c260=DO # Dominica ~c200,~c260=DMA # Dominica # Dominican Republic - bit 262 ~c200,~c262=DR # Dominican Republic ~c200,~c262=DOM # Dominican Republic # Ecuador - bit 264 ~c200,~c264=EC # Ecuador ~c200,~c264=ECU # Ecuador # Egypt - bit 265 ~c200,~c265=EG # Egypt ~c200,~c265=EGY # Egypt # Ireland - bit 305 ~c200,~c305=EI # Ireland ~c200,~c305=IRL # Ireland # Equatorial Guinea - bit 287 ~c200,~c287=EK # Equatorial Guinea ~c200,~c287=GNQ # Equatorial Guinea # Estonia - bit 269 ~c200,~c269=EN # Estonia ~c200,~c269=EST # Estonia # Eritrea - bit 266 ~c200,~c266=ER # Eritrea ~c200,~c266=ERI # Eritrea # El Salvador - bit 399 ~c200,~c399=ES # El Salvador ~c200,~c399=SLV # El Salvador # Ethiopia - bit 270 ~c200,~c270=ET # Ethiopia ~c200,~c270=ETH # Ethiopia # Czech Republic - bit 257 ~c200,~c257=CZE # Czech Republic #~c200,~c257=EZ # Czech Republic # French Guiana - bit 292 ~c200,~c292=FG # French Guiana ~c200,~c292=GUF # French Guiana # Finland - bit 271 ~c200,~c271=FI # Finland ~c200,~c271=FIN # Finland # Fiji - bit 272 ~c200,~c272=FJ # Fiji ~c200,~c272=FJI # Fiji # Falkland Islands (Islas Malvinas) - bit 273 ~c200,~c273=FK # Falkland Islands (Islas Malvinas) ~c200,~c273=FLK # Falkland Islands (Islas Malvinas) # Micronesia, Federated States of - bit 276 ~c200,~c276=FM # Micronesia, Federated States of ~c200,~c276=FSM # Micronesia, Federated States of # Faroe Islands - bit 275 ~c200,~c275=FO # Faroe Islands ~c200,~c275=FRO # Faroe Islands # French Polynesia - bit 384 ~c200,~c384=FP # French Polynesia ~c200,~c384=PYF # French Polynesia # France - bit 274 ~c200,~c274=FR # France ~c200,~c274=FRA # France # French Southern and Antarctic Lands - bit 213 ~c200,~c213=FS # French Southern and Antarctic Lands ~c200,~c213=ATF # French Southern and Antarctic Lands # Gambia, The - bit 285 ~c200,~c285=GA # Gambia, The ~c200,~c285=GMB # Gambia, The # Gabon - bit 277 ~c200,~c277=GB # Gabon ~c200,~c277=GAB # Gabon # Georgia - bit 279 ~c200,~c279=GG # Georgia ~c200,~c279=GEO # Georgia # Ghana - bit 281 ~c200,~c281=GH # Ghana ~c200,~c281=GHA # Ghana # Gibraltar - bit 282 ~c200,~c282=GI # Gibraltar ~c200,~c282=GIB # Gibraltar # Grenada - bit 289 ~c200,~c289=GJ # Grenada ~c200,~c289=GRD # Grenada # Guernsey - bit 280 part of UK ~c200,~c280=GK # Guernsey ~c200,~c280=GGY # Guernsey # Greenland - bit 290 ~c200,~c290=GL # Greenland ~c200,~c290=GRL # Greenland # Germany - bit 258 #~c200,~c258=GM # Germany ~c200,~c258=DEU # Germany # Guadeloupe - bit 284 ~c200,~c284=GP # Guadeloupe ~c200,~c284=GLP # Guadeloupe # Guam - bit 293 ~c200,~c293=GQ # Guam ~c200,~c293=GUM # Guam # Greece - bit 288 ~c200,~c288=GR # Greece ~c200,~c288=GRC # Greece # Guatemala - bit 291 ~c200,~c291=GT # Guatemala ~c200,~c291=GTM # Guatemala # Guinea - bit 283 ~c200,~c283=GV # Guinea ~c200,~c283=GIN # Guinea # Guyana - bit 294 ~c200,~c294=GY # Guyana ~c200,~c294=GUY # Guyana # Gaza Strip - bit 383 #~c200,~c383=GZ # Gaza Strip ~c200,~c383=PSE # Gaza Strip # Haiti - bit 299 ~c200,~c299=HA # Haiti ~c200,~c299=HTI # Haiti # Hong Kong - bit 295 ~c200,~c295=HK # Hong Kong ~c200,~c295=HKG # Hong Kong # Heard Island and McDonald Islands - bit 296 ~c200,~c296=HM # Heard Island and McDonald Islands ~c200,~c296=HMD # Heard Island and McDonald Islands # Honduras - bit 297 ~c200,~c297=HO # Honduras ~c200,~c297=HND # Honduras # Croatia - bit 298 ~c200,~c298=HR # Croatia ~c200,~c298=HRV # Croatia # Hungary - bit 300 ~c200,~c300=HU # Hungary ~c200,~c300=HUN # Hungary # Iceland - bit 308 ~c200,~c308=IC # Iceland ~c200,~c308=ISL # Iceland # Indonesia - bit 301 ~c200,~c301=ID # Indonesia ~c200,~c301=IDN # Indonesia # Isle of Man - bit 302 part of UK ~c200,~c302=IM # Isle of Man ~c200,~c302=IMN # Isle of Man # India - bit 303 ~c200,~c303=IN # India ~c200,~c303=IND # India # British Indian Ocean Territory - bit 304 ~c200,~c304=IO # British Indian Ocean Territory ~c200,~c304=IOT # British Indian Ocean Territory # Iran - bit 306 ~c200,~c306=IR # Iran ~c200,~c306=IRN # Iran # Israel - bit 309 ~c200,~c309=IS # Israel ~c200,~c309=ISR # Israel # Italy - bit 310 ~c200,~c310=IT # Italy ~c200,~c310=ITA # Italy # Cote d'Ivoire - bit 244 ~c200,~c244=IV # Cote d'Ivoire ~c200,~c244=CIV # Cote d'Ivoire # Iraq - bit 307 ~c200,~c307=IZ # Iraq ~c200,~c307=IRQ # Iraq # Japan - bit 314 ~c200,~c314=JA # Japan ~c200,~c314=JPN # Japan # Jersey - bit 312 part of UK ~c200,~c312=JE # Jersey ~c200,~c312=JEY # Jersey # Jamaica - bit 311 ~c200,~c311=JM # Jamaica ~c200,~c311=JAM # Jamaica # Jordan - bit 313 ~c200,~c313=JO # Jordan ~c200,~c313=JOR # Jordan # Kenya - bit 316 ~c200,~c316=KE # Kenya ~c200,~c316=KEN # Kenya # Kyrgyzstan - bit 317 ~c200,~c317=KG # Kyrgyzstan ~c200,~c317=KGZ # Kyrgyzstan # Korea, North - bit 380 ~c200,~c380=KN # Korea, North ~c200,~c380=PRK # Korea, North # Kiribati - bit 319 ~c200,~c319=KR # Kiribati ~c200,~c319=KIR # Kiribati # Korea, South - bit 321 ~c200,~c321=KS # Korea, South ~c200,~c321=ROK # Korea, South # Christmas Island - bit 254 ~c200,~c254=KT # Christmas Island ~c200,~c254=CXR # Christmas Island # Kuwait - bit 322 ~c200,~c322=KU # Kuwait ~c200,~c322=KWT # Kuwait # Kazakhstan - bit 315 ~c200,~c315=KZ # Kazakhstan ~c200,~c315=KAZ # Kazakhstan # Laos - bit 323 ~c200,~c323=LA # Laos ~c200,~c323=LAO # Laos # Lebanon - bit 324 ~c200,~c324=LE # Lebanon ~c200,~c324=LBN # Lebanon # Latvia - bit 333 ~c200,~c333=LG # Latvia ~c200,~c333=LVA # Latvia # Lithuania - bit 331 ~c200,~c331=LH # Lithuania ~c200,~c331=LTU # Lithuania # Liberia - bit 325 ~c200,~c325=LI # Liberia ~c200,~c325=LBR # Liberia # Slovakia - bit 406 ~c200,~c406=LO # Slovakia ~c200,~c406=SVK # Slovakia # Liechtenstein - bit 328 ~c200,~c328=LS # Liechtenstein ~c200,~c328=LIE # Liechtenstein # Lesotho - bit 330 ~c200,~c330=LT # Lesotho ~c200,~c330=LSO # Lesotho # Luxembourg - bit 332 ~c200,~c332=LU # Luxembourg ~c200,~c332=LUX # Luxembourg # Libya - bit 326 ~c200,~c326=LY # Libya ~c200,~c326=LBY # Libya # Madagascar - bit 339 ~c200,~c339=MA # Madagascar ~c200,~c339=MDG # Madagascar # Martinique - bit 353 ~c200,~c353=MB # Martinique ~c200,~c353=MTQ # Martinique # Macau - bit 334 ~c200,~c334=MC # Macau ~c200,~c334=MAC # Macau # Moldova - bit 338 ~c200,~c338=MD # Moldova ~c200,~c338=MDA # Moldova # Mayotte - bit 357 part of FRA ~c200,~c357=MF # Mayotte ~c200,~c357=MYT # Mayotte # Mongolia - bit 348 ~c200,~c348=MG # Mongolia ~c200,~c348=MNG # Mongolia # Montserrat - bit 352 ~c200,~c352=MH # Montserrat ~c200,~c352=MSR # Montserrat # Malawi - bit 355 ~c200,~c355=MI # Malawi ~c200,~c355=MWI # Malawi # Montenegro - bit 347 ~c200,~c347=MJ # Montenegro ~c200,~c347=MNE # Montenegro # Macedonia - bit 343 part of FYR ~c200,~c343=MK # Macedonia ~c200,~c343=MKD # Macedonia # Mali - bit 344 ~c200,~c344=ML # Mali ~c200,~c344=MLI # Mali # Monaco - bit 337 ~c200,~c337=MN # Monaco ~c200,~c337=MCO # Monaco # Morocco - bit 336 ~c200,~c336=MO # Morocco ~c200,~c336=MAR # Morocco # Mauritius - bit 354 ~c200,~c354=MP # Mauritius ~c200,~c354=MUS # Mauritius # Mauritania - bit 351 ~c200,~c351=MR # Mauritania ~c200,~c351=MRT # Mauritania # Malta - bit 345 ~c200,~c345=MT # Malta ~c200,~c345=MLT # Malta # Oman - bit 370 ~c200,~c370=MU # Oman ~c200,~c370=OMN # Oman # Maldives - bit 340 ~c200,~c340=MV # Maldives ~c200,~c340=MDV # Maldives # Mexico - bit 341 ~c200,~c341=MX # Mexico ~c200,~c341=MEX # Mexico # Malaysia - bit 356 ~c200,~c356=MY # Malaysia ~c200,~c356=MYS # Malaysia # Mozambique - bit 350 ~c200,~c350=MZ # Mozambique ~c200,~c350=MOZ # Mozambique # New Caledonia - bit 359 ~c200,~c359=NC # New Caledonia ~c200,~c359=NCL # New Caledonia # Niue - bit 364 ~c200,~c364=NE # Niue ~c200,~c364=NIU # Niue # Norfolk Island - bit 361 ~c200,~c361=NF # Norfolk Island ~c200,~c361=NFK # Norfolk Island # Niger - bit 360 ~c200,~c360=NG # Niger ~c200,~c360=NER # Niger # Vanuatu - bit 438 ~c200,~c438=NH # Vanuatu ~c200,~c438=VUT # Vanuatu # Nigeria - bit 362 ~c200,~c362=NI # Nigeria ~c200,~c362=NGA # Nigeria # Netherlands - bit 365 ~c200,~c365=NL # Netherlands ~c200,~c365=NLD # Netherlands # Norway - bit 366 ~c200,~c366=NO # Norway ~c200,~c366=NOR # Norway # Nepal - bit 367 ~c200,~c367=NP # Nepal ~c200,~c367=NPL # Nepal # Nauru - bit 368 ~c200,~c368=NR # Nauru ~c200,~c368=NRU # Nauru # Suriname - bit 405 ~c200,~c405=NS # Suriname ~c200,~c405=SUR # Suriname # Netherlands Antilles - bit 207 ~c200,~c207=NT # Netherlands Antilles ~c200,~c207=ANT # Netherlands Antilles # Nicaragua - bit 363 ~c200,~c363=NU # Nicaragua ~c200,~c363=NIC # Nicaragua # New Zealand - bit 369 ~c200,~c369=NZ # New Zealand ~c200,~c369=NZL # New Zealand # Paraguay - bit 382 ~c200,~c382=PA # Paraguay ~c200,~c382=PRY # Paraguay # Pitcairn Islands - bit 373 ~c200,~c373=PC # Pitcairn Islands ~c200,~c373=PCN # Pitcairn Islands # Peru - bit 374 ~c200,~c374=PE # Peru ~c200,~c374=PER # Peru # Pakistan - bit 371 ~c200,~c371=PK # Pakistan ~c200,~c371=PAK # Pakistan # Poland - bit 378 ~c200,~c378=PL # Poland ~c200,~c378=POL # Poland # Panama - bit 372 ~c200,~c372=PM # Panama ~c200,~c372=PAN # Panama # Portugal - bit 381 ~c200,~c381=PO # Portugal ~c200,~c381=PRT # Portugal # Papua New Guinea - bit 377 ~c200,~c377=PP # Papua New Guinea ~c200,~c377=PNG # Papua New Guinea # Palau - bit 376 #~c200,~c376=PS # Palau ~c200,~c376=PLW # Palau # Guinea-Bissau - bit 286 ~c200,~c286=PU # Guinea-Bissau ~c200,~c286=GNB # Guinea-Bissau # Qatar - bit 385 ~c200,~c385=QA # Qatar ~c200,~c385=QAT # Qatar # Serbia - bit 403 #~c200,~c403=RB # Serbia ~c200,~c403=SRB # Serbia # Reunion - bit 386 ~c200,~c386=RE # Reunion ~c200,~c386=REU # Reunion # Marshall Islands - bit 342 ~c200,~c342=RM # Marshall Islands ~c200,~c342=MHL # Marshall Islands # Saint Martin - bit 335 ~c200,~c335=RN # Saint Martin ~c200,~c335=MAF # Saint Martin # Romania - bit 387 ~c200,~c387=RO # Romania ~c200,~c387=ROU # Romania # Philippines - bit 375 ~c200,~c375=RP # Philippines ~c200,~c375=PHL # Philippines # Puerto Rico - bit 379 ~c200,~c379=RQ # Puerto Rico ~c200,~c379=PRI # Puerto Rico # Russia - bit 388 #~c200,~c388=RS # Russia ~c200,~c388=RUS # Russia # Rwanda - bit 389 ~c200,~c389=RW # Rwanda ~c200,~c389=RWA # Rwanda # Saudi Arabia - bit 390 ~c200,~c390=SA # Saudi Arabia ~c200,~c390=SAU # Saudi Arabia # Saint Pierre and Miquelon - bit 402 ~c200,~c402=SB # Saint Pierre and Miquelon ~c200,~c402=SPM # Saint Pierre and Miquelon # Saint Kitts and Nevis - bit 320 ~c200,~c320=SC # Saint Kitts and Nevis ~c200,~c320=KNA # Saint Kitts and Nevis # Seychelles - bit 410 ~c200,~c410=SE # Seychelles ~c200,~c410=SYC # Seychelles # South Africa - bit 442 ~c200,~c442=SF # South Africa ~c200,~c442=ZAF # South Africa # Senegal - bit 392 ~c200,~c392=SG # Senegal ~c200,~c392=SEN # Senegal # Saint Helena - bit 395 ~c200,~c395=SH # Saint Helena ~c200,~c395=SHN # Saint Helena # Slovenia - bit 407 #~c200,~c407=SI # Slovenia ~c200,~c407=SVN # Slovenia # Sierra Leone - bit 398 ~c200,~c398=SL # Sierra Leone ~c200,~c398=SLE # Sierra Leone # San Marino - bit 400 ~c200,~c400=SM # San Marino ~c200,~c400=SMR # San Marino # Singapore - bit 393 ~c200,~c393=SN # Singapore ~c200,~c393=SGP # Singapore # Somalia - bit 401 ~c200,~c401=SO # Somalia ~c200,~c401=SOM # Somalia # Spain - bit 268 #~c200,~c268=SP # Spain ~c200,~c268=ESP # Spain # Saint Lucia - bit 327 ~c200,~c327=ST # Saint Lucia ~c200,~c327=LCA # Saint Lucia # Sudan - bit 391 ~c200,~c391=SU # Sudan ~c200,~c391=SDN # Sudan # Svalbard - bit 396 #~c200,~c396=SV # Svalbard ~c200,~c396=SJM # Svalbard # Sweden - bit 408 ~c200,~c408=SW # Sweden ~c200,~c408=SWE # Sweden # South Georgia and the Islands - bit 394 ~c200,~c394=SX # South Georgia and the Islands ~c200,~c394=SGS # South Georgia and the Islands # Syria - bit 411 ~c200,~c411=SY # Syria ~c200,~c411=SYR # Syria # Switzerland - bit 241 ~c200,~c241=SZ # Switzerland ~c200,~c241=CHE # Switzerland # Saint Barthelemy - bit 227 ~c200,~c227=TB # Saint Barthelemy ~c200,~c227=BLM # Saint Barthelemy # Trinidad and Tobago - bit 421 ~c200,~c421=TD # Trinidad and Tobago ~c200,~c421=TTO # Trinidad and Tobago # Thailand - bit 415 ~c200,~c415=TH # Thailand ~c200,~c415=THA # Thailand # Tajikistan - bit 416 ~c200,~c416=TI # Tajikistan ~c200,~c416=TJK # Tajikistan # Turks and Caicos Islands - bit 412 ~c200,~c412=TK # Turks and Caicos Islands ~c200,~c412=TCA # Turks and Caicos Islands # Togo - bit 414 ~c200,~c414=TGO # Togo # Tokelau - bit 417 ~c200,~c417=TL # Tokelau ~c200,~c417=TKL # Tokelau # Tonga - bit 420 ~c200,~c420=TN # Tonga ~c200,~c420=TON # Tonga # Sao Tome and Principe - bit 404 ~c200,~c404=TP # Sao Tome and Principe ~c200,~c404=STP # Sao Tome and Principe # Tunisia - bit 422 ~c200,~c422=TS # Tunisia ~c200,~c422=TUN # Tunisia # Timor-Leste - bit 419 ~c200,~c419=TT # Timor-Leste ~c200,~c419=TLS # Timor-Leste # Turkey - bit 423 ~c200,~c423=TU # Turkey ~c200,~c423=TUR # Turkey # Tuvalu - bit 424 ~c200,~c424=TV # Tuvalu ~c200,~c424=TUV # Tuvalu # Taiwan - bit 425 ~c200,~c425=TW # Taiwan ~c200,~c425=TWN # Taiwan # Turkmenistan - bit 418 ~c200,~c418=TX # Turkmenistan ~c200,~c418=TKM # Turkmenistan # Tanzania - bit 426 ~c200,~c426=TZ # Tanzania ~c200,~c426=TZA # Tanzania # Uganda - bit 427 ~c200,~c427=UG # Uganda ~c200,~c427=UGA # Uganda # United Kingdom - bit 278 ~c200,~c278=UK # United Kingdom ~c200,~c278=GBR # United Kingdom # Ukraine - bit 428 ~c200,~c428=UP # Ukraine ~c200,~c428=UKR # Ukraine # United States - bit 430 ~c200,~c430=US # United States ~c200,~c430=USA # United States # Burkina Faso - bit 221 ~c200,~c221=UV # Burkina Faso ~c200,~c221=BFA # Burkina Faso # Uruguay - bit 429 ~c200,~c429=UY # Uruguay ~c200,~c429=URY # Uruguay # Uzbekistan - bit 431 ~c200,~c431=UZ # Uzbekistan ~c200,~c431=UZB # Uzbekistan # Saint Vincent and the Grenadines - bit 433 ~c200,~c433=VC # Saint Vincent and the Grenadines ~c200,~c433=VCT # Saint Vincent and the Grenadines # Venezuela - bit 434 ~c200,~c434=VE # Venezuela ~c200,~c434=VEN # Venezuela # British Virgin Islands - bit 435 ~c200,~c435=VI # British Virgin Islands ~c200,~c435=VGB # British Virgin Islands # Vietnam - bit 437 ~c200,~c437=VM # Vietnam ~c200,~c437=VNM # Vietnam # Virgin Islands - bit 436 #~c200,~c436=VQ # Virgin Islands ~c200,~c436=VIR # Virgin Islands # Holy See (Vatican City) - bit 432 ~c200,~c432=VT # Holy See (Vatican City) ~c200,~c432=VAT # Holy See (Vatican City) # Namibia - bit 358 ~c200,~c358=WA # Namibia ~c200,~c358=NAM # Namibia # West Bank - bit 383 ~c200,~c383=WE # West Bank # Wallis and Futuna - bit 439 ~c200,~c439=WF # Wallis and Futuna ~c200,~c439=WLF # Wallis and Futuna # Western Sahara - bit 267 ~c200,~c267=WI # Western Sahara ~c200,~c267=ESH # Western Sahara # Samoa - bit 440 #~c200,~c440=WS # Samoa ~c200,~c440=WSM # Samoa # Swaziland - bit 409 ~c200,~c409=WZ # Swaziland ~c200,~c409=SWZ # Swaziland # Yemen - bit 441 #~c200,~c441=YM # Yemen ~c200,~c441=YEM # Yemen # Zambia - bit 443 ~c200,~c443=ZA # Zambia ~c200,~c443=ZMB # Zambia # Zimbabwe - bit 444 ~c200,~c444=ZI # Zimbabwe ~c200,~c444=ZWE # Zimbabwe #UNCLASSIFIEDpolicycoreutils-2.3/mcstrans/share/examples/non-mls-color/000077500000000000000000000000001233221606300240565ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/non-mls-color/README000066400000000000000000000002461233221606300247400ustar00rootroot00000000000000Non-MLS color example To use: cp secolor.conf /etc/selinux/mls/ run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlscolor-test non-mls.color policycoreutils-2.3/mcstrans/share/examples/non-mls-color/non-mls.color000066400000000000000000000004501233221606300265000ustar00rootroot00000000000000system_u:system_r:inetd_t:SystemLow=#000000 #008000 #ffffff #000000 #d2b48c #ffa500 #000000 #008000 system_u:system_r:inetd_t:SystemHigh=#000000 #008000 #ffffff #000000 #d2b48c #ffa500 #000000 #008000 user_u:user_r:user_t:SystemLow=#000000 #008000 #ffffff #000000 #d2b48c #ffa500 #000000 #008000 policycoreutils-2.3/mcstrans/share/examples/non-mls-color/secolor.conf000066400000000000000000000003551233221606300263760ustar00rootroot00000000000000 color black = #000000 color green = #008000 color yellow = #ffff00 color blue = #0000ff color white = #ffffff color red = #ff0000 color orange = #ffa500 color tan = #D2B48C user * = black green role * = white black type * = tan orange policycoreutils-2.3/mcstrans/share/examples/pipes/000077500000000000000000000000001233221606300224775ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/pipes/pipes.test000066400000000000000000000006101233221606300245150ustar00rootroot00000000000000Restricted Handle Via Iron Pipes Only==s2:c102,c200.c511 Restricted Handle Via Copper Pipes Only==s2:c103,c200.c511 Restricted Handle Via Plastic Pipes Only==s2:c101,c200.c511 Restricted Handle Via Galvanized Pipes Only==s2:c104,c200.c511 Restricted Handle Via Plastic,Iron,Copper Pipes Only==s2:c101.c103,c200.c511 Restricted Handle Via Iron,Plastic,Copper Pipes Only=s2:c101.c103,c200.c511 policycoreutils-2.3/mcstrans/share/examples/pipes/setrans.conf000066400000000000000000000005251233221606300250270ustar00rootroot00000000000000 Domain=PipesTest s0=SystemLow s15:c0.c1023=SystemHigh s0-s15:c0.c1023=SystemLow-SystemHigh Base=Sensitivity Levels s1=Unclassified s1=U s2:c200.c511=Restricted s2:c200.c511=R s3:c200.c511=Confidential s3:c200.c511=C s4:c200.c511=Secret s4:c200.c511=S s5:c200.c511=Top Secret s5:c200.c511=TS Include=/etc/selinux/mls/setrans.d/pipes.conf policycoreutils-2.3/mcstrans/share/examples/pipes/setrans.d/000077500000000000000000000000001233221606300244005ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/pipes/setrans.d/pipes.conf000066400000000000000000000002171233221606300263670ustar00rootroot00000000000000ModifierGroup=Pipes Prefix=Handle Via Suffix=Pipes Only Suffix=Pipes Whitespace=, Join=, c101=Plastic c102=Iron c103=Copper c104=Galvanized policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/000077500000000000000000000000001233221606300251005ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/README000066400000000000000000000005451233221606300257640ustar00rootroot00000000000000Simple handling of UNCLASSIFIED RESTRICTED CONFIDENTIAL SECRET TOP SECRET via include files To use: cp -L setrans.conf /etc/selinux/mls/ cp -L secolor.conf /etc/selinux/mls/ rm -f /etc/selinux/mls/setrans.d/* cp setrans.d/* /etc/selinux/mls/setrans.d run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlstrans-test urcsts.test policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/secolor.conf000066400000000000000000000007371233221606300274240ustar00rootroot00000000000000 color black = #000000 color green = #008000 color yellow = #ffff00 color blue = #0000ff color white = #ffffff color red = #ff0000 color orange = #ffa500 color tan = #D2B48C user * = black black role * = black black type * = black black range s0-s0:c0.c1023 = black green range s1-s1:c0.c1023 = black green range s3-s3:c0.c1023 = black tan range s5-s5:c0.c1023 = white blue range s7-s7:c0.c1023 = black red range s9-s9:c0.c1023 = black orange range s15:c0.c1023 = black yellow policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/setrans.conf000066400000000000000000000007451233221606300274340ustar00rootroot00000000000000# # Multi-Level Security translation table for SELinux # # Uncomment the following to disable translation libary # disable=1 # # Objects can be labeled with one of 16 levels and be categorized with 0-1023 # categories defined by the admin. # Objects can be in more than one category at a time. # Users can modify this table to translate the MLS labels for different purpose. # # Demonstrate Include by moving everthing to an include file # Include=/etc/selinux/mls/setrans.d/*.conf policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/setrans.d/000077500000000000000000000000001233221606300270015ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/setrans.d/c.conf000066400000000000000000000001201233221606300300630ustar00rootroot00000000000000# UNCLASSIFIED s5=CONFIDENTIAL s5=C O N F I D E N T I A L s5=C # UNCLASSIFIED policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/setrans.d/r.conf000066400000000000000000000001121233221606300301030ustar00rootroot00000000000000# UNCLASSIFIED s3=RESTRICTED s3=R E S T R I C T E D s3=R # UNCLASSIFIED policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/setrans.d/s.conf000066400000000000000000000000761233221606300301150ustar00rootroot00000000000000# UNCLASSIFIED s7=SECRET s7=S E C R E T s7=S # UNCLASSIFIED policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/setrans.d/system.conf000066400000000000000000000001051233221606300311700ustar00rootroot00000000000000# UNCLASSIFIED s0=SystemLow s15:c0.c1023=SystemHigh # UNCLASSIFIED policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/setrans.d/ts.conf000066400000000000000000000001371233221606300302770ustar00rootroot00000000000000# UNCLASSIFIED s9=TOP SECRET s9=T O P S E C R E T s9=T O P S E C R E T s9=TS # UNCLASSIFIED policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/setrans.d/u.conf000066400000000000000000000000771233221606300301200ustar00rootroot00000000000000# UNCLASSIFIED s1=UNCLASSIFIED s1=UNCLAS s1=U # UNCLASSIFIED policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/urcsts.color000066400000000000000000000036341233221606300274710ustar00rootroot00000000000000system_u:system_r:inetd_t:SystemLow=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s0=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s0:c1=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:UNCLASSIFIED=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s1=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s1:c2=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:RESTRICTED=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:s3=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:s3:c3=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:CONFIDENTIAL=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:s5=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:s5:c0.c5=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:SECRET=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:s7=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:s7:c200.c300=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:TOP SECRET=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s9=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s9:c1023=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s15=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffff00 system_u:system_r:inetd_t:SystemHigh=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffff00 policycoreutils-2.3/mcstrans/share/examples/urcsts-via-include/urcsts.test000066400000000000000000000004451233221606300273270ustar00rootroot00000000000000# UNCLASSIFIED SystemLow=s0 SystemHigh=s15:c0.c1023 UNCLASSIFIED==s1 UNCLAS=s1 U=s1 RESTRICTED==s3 R E S T R I C T E D=s3 R=s3 CONFIDENTIAL==s5 C O N F I D E N T I A L=s5 C=s5 SECRET==s7 S E C R E T=s7 S=s7 TOP SECRET==s9 T O P S E C R E T=s9 T O P S E C R E T=s9 TS=s9 # UNCLASSIFIED policycoreutils-2.3/mcstrans/share/examples/urcsts/000077500000000000000000000000001233221606300227025ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/examples/urcsts/README000066400000000000000000000004771233221606300235720ustar00rootroot00000000000000Simple handling of UNCLASSIFIED RESTRICTED CONFIDENTIAL SECRET TOP SECRET To use: cp setrans.conf /etc/selinux/mls/setrans.conf cp secolor.conf /etc/selinux/mls/ run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlstrans-test urcsts.test /usr/share/mcstrans/util/mlscolor-test urcsts.color policycoreutils-2.3/mcstrans/share/examples/urcsts/secolor.conf000066400000000000000000000007371233221606300252260ustar00rootroot00000000000000 color black = #000000 color green = #008000 color yellow = #ffff00 color blue = #0000ff color white = #ffffff color red = #ff0000 color orange = #ffa500 color tan = #D2B48C user * = black black role * = black black type * = black black range s0-s0:c0.c1023 = black green range s1-s1:c0.c1023 = black green range s3-s3:c0.c1023 = black tan range s5-s5:c0.c1023 = white blue range s7-s7:c0.c1023 = black red range s9-s9:c0.c1023 = black orange range s15:c0.c1023 = black yellow policycoreutils-2.3/mcstrans/share/examples/urcsts/setrans.conf000066400000000000000000000004401233221606300252260ustar00rootroot00000000000000# UNCLASSIFIED s0=SystemLow s15:c0.c1023=SystemHigh s1=UNCLASSIFIED s1=UNCLAS s1=U s3=RESTRICTED s3=R E S T R I C T E D s3=R s5=CONFIDENTIAL s5=C O N F I D E N T I A L s5=C s7=SECRET s7=S E C R E T s7=S s9=TOP SECRET s9=T O P S E C R E T s9=T O P S E C R E T s9=TS # UNCLASSIFIED policycoreutils-2.3/mcstrans/share/examples/urcsts/urcsts.color000066400000000000000000000036341233221606300252730ustar00rootroot00000000000000system_u:system_r:inetd_t:SystemLow=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s0=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s0:c1=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:UNCLASSIFIED=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s1=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s1:c2=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:RESTRICTED=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:s3=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:s3:c3=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:CONFIDENTIAL=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:s5=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:s5:c0.c5=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:SECRET=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:s7=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:s7:c200.c300=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:TOP SECRET=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s9=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s9:c1023=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s15=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffff00 system_u:system_r:inetd_t:SystemHigh=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffff00 policycoreutils-2.3/mcstrans/share/examples/urcsts/urcsts.test000066400000000000000000000004451233221606300251310ustar00rootroot00000000000000# UNCLASSIFIED SystemLow=s0 SystemHigh=s15:c0.c1023 UNCLASSIFIED==s1 UNCLAS=s1 U=s1 RESTRICTED==s3 R E S T R I C T E D=s3 R=s3 CONFIDENTIAL==s5 C O N F I D E N T I A L=s5 C=s5 SECRET==s7 S E C R E T=s7 S=s7 TOP SECRET==s9 T O P S E C R E T=s9 T O P S E C R E T=s9 TS=s9 # UNCLASSIFIED policycoreutils-2.3/mcstrans/share/util/000077500000000000000000000000001233221606300205165ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/share/util/mlscolor-test000066400000000000000000000021071233221606300232500ustar00rootroot00000000000000#!/usr/bin/python -E import sys, re from selinux import * verbose = 0 errors=0 if len(sys.argv) > 1 and sys.argv[1] == "-v": verbose = 1 for arg in sys.argv[1:]: f=open(arg, 'r') for line in f: if line.startswith('#'): continue if not line.strip(): continue line = line.rstrip('\n') # print line context,expected=line.split("="); rc, raw = selinux_trans_to_raw_context(context) if rc < 0: print "Unable to get raw context of '%s'" % (context) errors += 1 continue rc, colors = selinux_raw_context_to_color(raw) if rc < 0: print "Unable to get colors for '%s'" % (context) errors += 1 continue colors = colors.rstrip() if colors != expected: print "For '%s' got\n\t'%s' expected\n\t'%s'" % (context,colors,expected) errors += 1 continue f.close() s = "s" if errors == 1: s = "" print "mlscolor-test done with %d error%s" % (errors, s) sys.exit(errors) policycoreutils-2.3/mcstrans/share/util/mlstrans-test000066400000000000000000000025561233221606300232710ustar00rootroot00000000000000#!/usr/bin/python -E import sys, re from selinux import * verbose = 0 errors=0 def untrans(trans, val): global errors, verbose (rc, raw) = selinux_trans_to_raw_context(trans) if raw != val: print "untrans: '%s' -> '%s' != '%s' FAILED" % (trans, raw, val) errors += 1 else: if verbose: print "untrans: %s -> %s != %s SUCCESS" % (trans, raw, val) def trans(raw, val): global errors, verbose (rc, trans) = selinux_raw_to_trans_context(raw) if trans != val: print "trans: '%s' -> '%s' != '%s' FAILED" % (raw,trans, val) errors += 1 else: if verbose: print "trans: %s -> %s != %s SUCCESS" % (raw, trans, val) if len(sys.argv) > 1 and sys.argv[1] == "-v": verbose = 1 for arg in sys.argv[1:]: f=open(arg, 'r') for line in f: if line.startswith('#'): continue if not line.strip(): continue line = line.rstrip('\n') # print line if (line.find("==") != -1): t,r=line.split("=="); untrans("a:b:c:" + t, "a:b:c:" + r) trans("a:b:c:" + r, "a:b:c:" + t) else: t,r=line.split("="); untrans("a:b:c:" + t, "a:b:c:" + r) f.close() s = "s" if errors == 1: s = "" print "mlstrans-test done with %d error%s" % (errors, s) sys.exit(errors) policycoreutils-2.3/mcstrans/share/util/try-all000066400000000000000000000033411233221606300220260ustar00rootroot00000000000000#!/bin/bash shopt -s nullglob fail() { echo $1 exit 1 } [ `id -u` = 0 ] || fail "must run as root" for d in /usr/share/mcstrans/examples/*; do echo $d rm -rf /etc/selinux/mls/setrans.conf.bak /etc/selinux/mls/secolor.conf.bak /etc/selinux/mls/setrans.d.bak [ $? -eq 0 ] || fail "preclean failed" if [ -e $d/setrans.conf ]; then mv /etc/selinux/mls/setrans.conf /etc/selinux/mls/setrans.conf.bak [ $? -eq 0 ] || fail "setrans.conf backup failed" fi if [ -e /etc/selinux/mls/secolor.conf ]; then mv /etc/selinux/mls/secolor.conf /etc/selinux/mls/secolor.conf.bak [ $? -eq 0 ] || fail "secolor.conf backup failed" fi mv /etc/selinux/mls/setrans.d /etc/selinux/mls/setrans.d.bak [ $? -eq 0 ] || fail "setrans.d backup failed" if [ -e $d/setrans.conf ]; then cp -L $d/setrans.conf /etc/selinux/mls/setrans.conf fi if [ -e $d/secolor.conf ]; then cp -L $d/secolor.conf /etc/selinux/mls fi if [ -d $d/setrans.d ]; then cp -Lr $d/setrans.d /etc/selinux/mls fi runcon `cat /etc/selinux/mls/contexts/initrc_context` /etc/init.d/mcstrans restart for t in $d/*.test; do /usr/share/mcstrans/util/mlstrans-test $t done for c in $d/*.color; do /usr/share/mcstrans/util/mlscolor-test $c done if [ -e /etc/selinux/mls/setrans.conf.bak ]; then mv /etc/selinux/mls/setrans.conf.bak /etc/selinux/mls/setrans.conf fi if [ -e /etc/selinux/mls/secolor.conf.bak ]; then mv /etc/selinux/mls/secolor.conf.bak /etc/selinux/mls/secolor.conf fi rm -rf /etc/selinux/mls/setrans.d mv /etc/selinux/mls/setrans.d.bak /etc/selinux/mls/setrans.d restorecon -rv /etc/selinux/mls/setrans.conf /etc/selinux/mls/setrans.d >/dev/null runcon `cat /etc/selinux/mls/contexts/initrc_context` /etc/init.d/mcstrans restart done exit 0 policycoreutils-2.3/mcstrans/src/000077500000000000000000000000001233221606300172265ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/src/Makefile000066400000000000000000000024521233221606300206710ustar00rootroot00000000000000ARCH = $(shell uname -i) ifeq "$(ARCH)" "x86_64" # In case of 64 bit system, use these lines LIBDIR=/usr/lib64 else ifeq "$(ARCH)" "i686" # In case of 32 bit system, use these lines LIBDIR=/usr/lib else ifeq "$(ARCH)" "i386" # In case of 32 bit system, use these lines LIBDIR=/usr/lib endif endif endif # Installation directories. PREFIX ?= $(DESTDIR)/usr SBINDIR ?= $(DESTDIR)/sbin INITDIR ?= $(DESTDIR)/etc/rc.d/init.d SYSTEMDDIR ?= $(DESTDIR)/usr/lib/systemd PROG_SRC=mcstrans.c mcscolor.c mcstransd.c mls_level.c PROG_OBJS= $(patsubst %.c,%.o,$(PROG_SRC)) PROG=mcstransd INITSCRIPT=mcstrans CFLAGS ?= -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute override CFLAGS += -I../include -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 all: $(PROG) $(PROG): $(PROG_OBJS) $(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap -lpcre $(LIBDIR)/libsepol.a %.o: %.c $(CC) $(CFLAGS) -fPIE -c -o $@ $< install: all test -d $(SBINDIR) || install -m 755 -d $(SBINDIR) install -m 755 $(PROG) $(SBINDIR) test -d $(INITDIR) || install -m 755 -d $(INITDIR) install -m 755 $(INITSCRIPT).init $(INITDIR)/$(INITSCRIPT) test -d $(SYSTEMDDIR)/system || install -m 755 -d $(SYSTEMDDIR)/system install -m 644 mcstrans.service $(SYSTEMDDIR)/system/ clean: -rm -f $(OBJS) $(LOBJS) $(TARGET) $(PROG) $(PROG_OBJS) *~ \#* policycoreutils-2.3/mcstrans/src/README000066400000000000000000000002331233221606300201040ustar00rootroot00000000000000To rebuild with debugging support: make clean && env CFLAGS="-Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute -DDEBUG -g" LDFLAGS="-g" make policycoreutils-2.3/mcstrans/src/mcscolor.c000066400000000000000000000153701233221606300212210ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mcstrans.h" /* Define data structures */ typedef struct secolor { uint32_t fg; uint32_t bg; } secolor_t; typedef struct semnemonic { char *name; uint32_t color; struct semnemonic *next; } semnemonic_t; typedef struct setab { char *pattern; secolor_t color; struct setab *next; } setab_t; #define COLOR_USER 0 #define COLOR_ROLE 1 #define COLOR_TYPE 2 #define COLOR_RANGE 3 #define N_COLOR 4 #define AUX_RULE_COLOR "color" static char *rules[] = { "user", "role", "type", "range" }; static setab_t *clist[N_COLOR]; static setab_t *cend[N_COLOR]; static semnemonic_t *mnemonics; static security_context_t my_context; void finish_context_colors(void) { setab_t *cur, *next; semnemonic_t *ptr; unsigned i; for (i = 0; i < N_COLOR; i++) { cur = clist[i]; while(cur) { next = cur->next; free(cur->pattern); free(cur); cur = next; } clist[i] = cend[i] = NULL; } ptr = mnemonics; while (ptr) { mnemonics = ptr->next; free(ptr->name); free(ptr); ptr = mnemonics; } mnemonics = NULL; freecon(my_context); my_context = NULL; } static int check_dominance(const char *pattern, const char *raw) { security_context_t ctx; context_t con; unsigned int bit = CONTEXT__CONTAINS; struct av_decision avd; int rc = -1; context_t my_tmp; const char *raw_range; con = context_new(raw); if (!con) return -1; raw_range = context_range_get(con); my_tmp = context_new(my_context); if (!my_tmp) { context_free(con); return -1; } ctx = NULL; if (context_range_set(my_tmp, pattern)) goto out; ctx = strdup(context_str(my_tmp)); if (!ctx) goto out; if (context_range_set(my_tmp, raw_range)) goto out; raw = context_str(my_tmp); if (!raw) goto out; rc = security_compute_av_raw(ctx, (security_context_t)raw, SECCLASS_CONTEXT, bit, &avd); if (rc) goto out; rc = (bit & avd.allowed) != bit; out: free(ctx); context_free(my_tmp); context_free(con); return rc; } static const secolor_t *find_color(int idx, const char *component, const char *raw) { setab_t *ptr = clist[idx]; if (idx == COLOR_RANGE) { if (!raw) { return NULL; } } else if (!component) { return NULL; } while (ptr) { if (fnmatch(ptr->pattern, component, 0) == 0) { if (idx == COLOR_RANGE) { if (check_dominance(ptr->pattern, raw) == 0) return &ptr->color; } else return &ptr->color; } ptr = ptr->next; } return NULL; } static int add_secolor(int idx, char *pattern, uint32_t fg, uint32_t bg) { setab_t *cptr; cptr = calloc(1, sizeof(setab_t)); if (!cptr) return -1; cptr->pattern = strdup(pattern); if (!cptr->pattern) { free(cptr); return -1; } cptr->color.fg = fg & 0xffffff; cptr->color.bg = bg & 0xffffff; if (cend[idx]) { cend[idx]->next = cptr; cend[idx] = cptr; } else { clist[idx] = cptr; cend[idx] = cptr; } return 0; } static int find_mnemonic(const char *name, uint32_t *retval) { semnemonic_t *ptr; if (*name == '#') return sscanf(name, "#%x", retval) == 1 ? 0 : -1; ptr = mnemonics; while (ptr) { if (!strcmp(ptr->name, name)) { *retval = ptr->color; return 0; } ptr = ptr->next; } return -1; } static int add_mnemonic(const char *name, uint32_t color) { semnemonic_t *ptr = malloc(sizeof(semnemonic_t)); if (!ptr) return -1; ptr->color = color; ptr->name = strdup(name); if (!ptr->name) { free(ptr); return -1; } ptr->next = mnemonics; mnemonics = ptr; return 0; } /* Process line from color file. May modify the data pointed to by the buffer paremeter */ static int process_color(char *buffer, int line) { char rule[10], pat[256], f[256], b[256]; uint32_t i, fg, bg; int ret; while(isspace(*buffer)) buffer++; if(buffer[0] == '#' || buffer[0] == '\0') return 0; ret = sscanf(buffer, "%8s %255s = %255s %255s", rule, pat, f, b); if (ret == 4) { if (find_mnemonic(f, &fg) == 0 && find_mnemonic(b, &bg) == 0) for (i = 0; i < N_COLOR; i++) if (!strcmp(rule, rules[i])) return add_secolor(i, pat, fg, bg); } else if (ret == 3) { if (!strcmp(rule, AUX_RULE_COLOR)) { if (sscanf(f, "#%x", &fg) == 1) return add_mnemonic(pat, fg); } } syslog(LOG_WARNING, "Line %d of secolors file is invalid.", line); return 0; } /* Read in color file. */ int init_colors(void) { FILE *cfg = NULL; size_t size = 0; char *buffer = NULL; int line = 0; getcon(&my_context); cfg = fopen(selinux_colors_path(), "r"); if (!cfg) return 1; __fsetlocking(cfg, FSETLOCKING_BYCALLER); while (getline(&buffer, &size, cfg) > 0) { if( process_color(buffer, ++line) < 0 ) break; } free(buffer); fclose(cfg); return 0; } static const unsigned precedence[N_COLOR][N_COLOR - 1] = { { COLOR_ROLE, COLOR_TYPE, COLOR_RANGE }, { COLOR_USER, COLOR_TYPE, COLOR_RANGE }, { COLOR_USER, COLOR_ROLE, COLOR_RANGE }, { COLOR_USER, COLOR_ROLE, COLOR_TYPE }, }; static const secolor_t default_color = { 0x000000, 0xffffff }; static int parse_components(context_t con, char **components) { components[COLOR_USER] = (char *)context_user_get(con); components[COLOR_ROLE] = (char *)context_role_get(con); components[COLOR_TYPE] = (char *)context_type_get(con); components[COLOR_RANGE] = (char *)context_range_get(con); return 0; } /* Look up colors. */ int raw_color(const security_context_t raw, char **color_str) { #define CHARS_PER_COLOR 16 context_t con; uint32_t i, j, mask = 0; const secolor_t *items[N_COLOR]; char *result, *components[N_COLOR]; char buf[CHARS_PER_COLOR + 1]; int rc = -1; if (!color_str && !*color_str) { return -1; } /* parse context and allocate memory */ con = context_new(raw); if (!con) return -1; if (parse_components(con, components) < 0) goto out; result = malloc((N_COLOR * CHARS_PER_COLOR) + 1); if (!result) goto out; result[0] = '\0'; /* find colors for which we have a match */ for (i = 0; i < N_COLOR; i++) { items[i] = find_color(i, components[i], raw); if (items[i]) mask |= (1 << i); } if (mask == 0) { items[0] = &default_color; mask = 1; } /* propagate colors according to the precedence rules */ for (i = 0; i < N_COLOR; i++) if (!(mask & (1 << i))) for (j = 0; j < N_COLOR - 1; j++) if (mask & (1 << precedence[i][j])) { items[i] = items[precedence[i][j]]; break; } /* print results into a big long string */ for (i = 0; i < N_COLOR; i++) { snprintf(buf, sizeof(buf), "#%06x #%06x ", items[i]->fg, items[i]->bg); strncat(result, buf, sizeof(buf)); } *color_str = result; rc = 0; out: context_free(con); return rc; } policycoreutils-2.3/mcstrans/src/mcstrans.c000066400000000000000000001203271233221606300212310ustar00rootroot00000000000000 /* Copyright (c) 2008-2009 Nall Design Works Copyright 2006 Trusted Computer Solutions, Inc. */ /* Exported Interface int init_translations(void); void finish_context_translations(void); int trans_context(const security_context_t, security_context_t *); int untrans_context(const security_context_t, security_context_t *); */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mls_level.h" #include "mcstrans.h" #define N_BUCKETS 1453 #define OVECCOUNT (512*3) #define log_error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) #ifdef DEBUG #define log_debug(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) #else #define log_debug(fmt, ...) ; #endif static unsigned int maxbit=0; /* Define data structures */ typedef struct context_map { char *raw; char *trans; } context_map_t; typedef struct context_map_node { char *key; context_map_t *map; struct context_map_node *next; } context_map_node_t; typedef struct affix { char *text; struct affix *next; } affix_t; typedef struct word { char *text; ebitmap_t cat; ebitmap_t normal; ebitmap_t inverse; struct word *next; } word_t; typedef struct word_group { char *name; char *whitespace; char *join; affix_t *prefixes; affix_t *suffixes; word_t *words; pcre *prefix_regexp; pcre *word_regexp; pcre *suffix_regexp; ebitmap_t def; word_t **sword; int sword_len; struct word_group *next; } word_group_t; typedef struct base_classification { char *trans; mls_level_t *level; struct base_classification *next; } base_classification_t; typedef struct domain { char *name; context_map_node_t *raw_to_trans[N_BUCKETS]; context_map_node_t *trans_to_raw[N_BUCKETS]; base_classification_t *base_classifications; word_group_t *groups; pcre *base_classification_regexp; struct domain *next; } domain_t; static domain_t *domains; typedef struct sens_constraint { char op; char *text; unsigned int sens; ebitmap_t cat; struct sens_constraint *next; } sens_constraint_t; static sens_constraint_t *sens_constraints; typedef struct cat_constraint { char op; char *text; int nbits; ebitmap_t mask; ebitmap_t cat; struct cat_constraint *next; } cat_constraint_t; static cat_constraint_t *cat_constraints; unsigned int hash(const char *str) { unsigned int hash = 5381; int c; while ((c = *(unsigned const char *)str++)) hash = ((hash << 5) + hash) + c; return hash; } static int add_to_hashtable(context_map_node_t **table, char *key, context_map_t *map) { unsigned int bucket = hash(key) % N_BUCKETS; context_map_node_t **n; for (n = &table[bucket]; *n; n = &(*n)->next) ; *n = malloc(sizeof(context_map_node_t)); if (! *n) goto err; (*n)->key = key; (*n)->map = map; (*n)->next = NULL; return 0; err: syslog(LOG_ERR, "add_to_hashtable: allocation error"); return -1; } static int numdigits(unsigned int n) { int count = 1; while ((n = n / 10)) count++; return count; } static int parse_category(ebitmap_t *e, const char *raw, int allowinverse) { int inverse = 0; unsigned int low, high; while (*raw) { if (allowinverse && *raw == '~') { inverse = !inverse; raw++; continue; } if (sscanf(raw,"c%u", &low) != 1) return -1; raw += numdigits(low) + 1; if (*raw == '.') { raw++; if (sscanf(raw,"c%u", &high) != 1) return -1; raw += numdigits(high) + 1; } else { high = low; } while (low <= high) { if (low >= maxbit) maxbit = low + 1; if (ebitmap_set_bit(e, low, inverse ? 0 : 1) < 0) return -1; low++; } if (*raw == ',') { raw++; inverse = 0; } else if (*raw != '\0') { return -1; } } return 0; } int parse_ebitmap(ebitmap_t *e, ebitmap_t *def, const char *raw) { int rc = ebitmap_cpy(e, def); if (rc < 0) return rc; rc = parse_category(e, raw, 1); if (rc < 0) return rc; return 0; } mls_level_t * parse_raw(const char *raw) { mls_level_t *mls = calloc(1, sizeof(mls_level_t)); if (!mls) goto err; if (sscanf(raw,"s%u", &mls->sens) != 1) goto err; raw += numdigits(mls->sens) + 1; if (*raw == ':') { raw++; if (parse_category(&mls->cat, raw, 0) < 0) goto err; } else if (*raw != '\0') { goto err; } return mls; err: ebitmap_destroy(&mls->cat); free(mls); return NULL; } void destroy_word(word_t **list, word_t *word) { if (!word) { return; } for (; list && *list; list = &(*list)->next) { if (*list == word) { *list = word->next; break; } } free(word->text); ebitmap_destroy(&word->cat); ebitmap_destroy(&word->normal); ebitmap_destroy(&word->inverse); memset(word, 0, sizeof(word_t)); free(word); } word_t * create_word(word_t **list, const char *text) { word_t *w = calloc(1, sizeof(word_t)); if (!w) { goto err; } w->text = strdup(text); if (!w->text) { goto err; } if (list) { for (; *list; list = &(*list)->next) ; *list = w; } return w; err: log_error("create_word: allocation error %s", strerror(errno)); destroy_word(NULL, w); return NULL; } void destroy_group(word_group_t **list, word_group_t *group) { for (; list && *list; list = &(*list)->next) { if (*list == group) { *list = group->next; break; } } while(group->prefixes) { affix_t *next = group->prefixes->next; free(group->prefixes->text); free(group->prefixes); group->prefixes=next; } while(group->suffixes) { affix_t *next = group->suffixes->next; free(group->suffixes->text); free(group->suffixes); group->suffixes=next; } while(group->words) destroy_word(&group->words, group->words); free(group->whitespace); free(group->name); free(group->sword); free(group->join); pcre_free(group->prefix_regexp); pcre_free(group->word_regexp); pcre_free(group->suffix_regexp); ebitmap_destroy(&group->def); free(group); } word_group_t * create_group(word_group_t **list, const char *name) { word_group_t *group = calloc(1, sizeof(word_group_t)); if (!group) return NULL; group->name = strdup(name); if (!group->name) { goto err; } group->join = strdup(" "); if (!group->join) { goto err; } group->whitespace = strdup(" "); if (!group->whitespace) { goto err; } group->sword = NULL; if (list) { for (; *list; list = &(*list)->next) ; *list = group; } return group; err: log_error("allocation error %s", strerror(errno)); destroy_group(NULL, group); return NULL; } void destroy_domain(domain_t *domain) { int i; unsigned int rt = 0, tr = 0; for (i=0; i < N_BUCKETS; i++) { context_map_node_t *ptr; for (ptr = domain->trans_to_raw[i]; ptr;) { context_map_node_t *t = ptr->next; free(ptr); ptr = t; tr++; } domain->trans_to_raw[i] = NULL; } for (i=0; i < N_BUCKETS; i++) { context_map_node_t *ptr; for (ptr = domain->raw_to_trans[i]; ptr;) { context_map_node_t *t = ptr->next; free(ptr->map->raw); free(ptr->map->trans); free(ptr->map); free(ptr); ptr = t; rt++; } domain->raw_to_trans[i] = NULL; } while (domain->base_classifications) { base_classification_t *next = domain->base_classifications->next; free(domain->base_classifications->trans); ebitmap_destroy(&domain->base_classifications->level->cat); free(domain->base_classifications->level); free(domain->base_classifications); domain->base_classifications = next; } pcre_free(domain->base_classification_regexp); while (domain->groups) destroy_group(&domain->groups, domain->groups); free(domain->name); free(domain); syslog(LOG_INFO, "cache sizes: tr = %u, rt = %u", tr, rt); } domain_t * create_domain(const char *name) { domain_t *domain = calloc(1, sizeof(domain_t)); if (!domain) { goto err; } domain->name = strdup(name); if (!domain->name) { goto err; } domain_t **d = &domains; for (; *d; d = &(*d)->next) ; *d = domain; return domain; err: log_error("allocation error %s", strerror(errno)); destroy_domain(domain); return NULL; } int add_word(word_group_t *group, char *raw, char *trans) { if (strchr(trans,'-')) { log_error("'%s'is invalid because '-' is illegal in modifiers.\n", trans); return -1; } word_t *word = create_word(&group->words, trans); int rc = parse_ebitmap(&word->cat, &group->def, raw); if (rc < 0) { log_error(" syntax error in %s\n", raw); destroy_word(&group->words, word); return -1; } if (ebitmap_andnot(&word->normal, &word->cat, &group->def, maxbit) < 0) return -1; ebitmap_t temp; if (ebitmap_xor(&temp, &word->cat, &group->def) < 0) return -1; if (ebitmap_and(&word->inverse, &temp, &group->def) < 0) return -1; ebitmap_destroy(&temp); return 0; } int add_constraint(char op, char *raw, char *tok) { log_debug("%s\n", "add_constraint"); ebitmap_t empty; ebitmap_init(&empty); if (!raw || !*raw) { syslog(LOG_ERR, "unable to parse line"); return -1; } if (*raw == 's') { sens_constraint_t *constraint = calloc(1, sizeof(sens_constraint_t)); if (!constraint) { log_error("allocation error %s", strerror(errno)); return -1; } if (sscanf(raw,"s%u", &constraint->sens) != 1) { syslog(LOG_ERR, "unable to parse level"); free(constraint); return -1; } if (parse_ebitmap(&constraint->cat, &empty, tok) < 0) { syslog(LOG_ERR, "unable to parse cat"); free(constraint); return -1; } if (asprintf(&constraint->text, "%s%c%s", raw, op, tok) < 0) { log_error("asprintf failed %s", strerror(errno)); return -1; } constraint->op = op; sens_constraint_t **p; for (p= &sens_constraints; *p; p = &(*p)->next) ; *p = constraint; return 0; } else if (*raw == 'c' ) { cat_constraint_t *constraint = calloc(1, sizeof(cat_constraint_t)); if (!constraint) { log_error("allocation error %s", strerror(errno)); return -1; } if (parse_ebitmap(&constraint->mask, &empty, raw) < 0) { syslog(LOG_ERR, "unable to parse mask"); free(constraint); return -1; } if (parse_ebitmap(&constraint->cat, &empty, tok) < 0) { syslog(LOG_ERR, "unable to parse cat"); ebitmap_destroy(&constraint->mask); free(constraint); return -1; } if (asprintf(&constraint->text, "%s%c%s", raw, op, tok) < 0) { log_error("asprintf failed %s", strerror(errno)); return -1; } constraint->nbits = ebitmap_cardinality(&constraint->cat); constraint->op = op; cat_constraint_t **p; for (p= &cat_constraints; *p; p = &(*p)->next) ; *p = constraint; return 0; } else { return -1; } return 0; } int violates_constraints(mls_level_t *l) { int nbits; sens_constraint_t *s; for (s=sens_constraints; s; s=s->next) { if (s->sens == l->sens) { ebitmap_t common; if (ebitmap_and(&common, &s->cat, &l->cat) < 0) return 1; nbits = ebitmap_cardinality(&common); ebitmap_destroy(&common); if (nbits) { char *text = mls_level_to_string(l); syslog(LOG_WARNING, "%s violates %s", text, s->text); free(text); return 1; } } } cat_constraint_t *c; for (c=cat_constraints; c; c=c->next) { ebitmap_t common; if (ebitmap_and(&common, &c->mask, &l->cat) < 0) return 1; nbits = ebitmap_cardinality(&common); ebitmap_destroy(&common); if (nbits > 0) { ebitmap_t common; if (ebitmap_and(&common, &c->cat, &l->cat) < 0) return 1; nbits = ebitmap_cardinality(&common); ebitmap_destroy(&common); if ((c->op == '!' && nbits) || (c->op == '>' && nbits != c->nbits)) { char *text = mls_level_to_string(l); syslog(LOG_WARNING, "%s violates %s (%d,%d)", text, c->text, nbits, c->nbits); free(text); return 1; } } } return 0; } void destroy_sens_constraint(sens_constraint_t **list, sens_constraint_t *constraint) { if (!constraint) { return; } for (; list && *list; list = &(*list)->next) { if (*list == constraint) { *list = constraint->next; break; } } ebitmap_destroy(&constraint->cat); free(constraint->text); memset(constraint, 0, sizeof(sens_constraint_t)); free(constraint); } void destroy_cat_constraint(cat_constraint_t **list, cat_constraint_t *constraint) { if (!constraint) { return; } for (; list && *list; list = &(*list)->next) { if (*list == constraint) { *list = constraint->next; break; } } ebitmap_destroy(&constraint->mask); ebitmap_destroy(&constraint->cat); free(constraint->text); memset(constraint, 0, sizeof(cat_constraint_t)); free(constraint); } static int add_base_classification(domain_t *domain, char *raw, char *trans) { mls_level_t *level = parse_raw(raw); if (level) { base_classification_t **i; base_classification_t *base_classification = calloc(1, sizeof(base_classification_t)); if (!base_classification) { log_error("allocation error %s", strerror(errno)); return -1; } base_classification->trans=strdup(trans); if (!base_classification->trans) { log_error("allocation error %s", strerror(errno)); free(base_classification); return -1; } base_classification->level=level; for (i=&domain->base_classifications; *i; i=&(*i)->next) ; *i = base_classification; return 0; } log_error(" add_base_classification error %s %s\n", raw, trans); return -1; } static int add_cache(domain_t *domain, char *raw, char *trans) { context_map_t *map = calloc(1, sizeof(context_map_t)); if (!map) goto err; map->raw = strdup(raw); if (!map->raw) { goto err; } map->trans = strdup(trans); if (!map->trans) { goto err; } log_debug(" add_cache (%s,%s)\n", raw, trans); if (add_to_hashtable(domain->raw_to_trans, map->raw, map) < 0) goto err; if (add_to_hashtable(domain->trans_to_raw, map->trans, map) < 0) goto err; return 0; err: log_error("%s: allocation error", "add_cache"); return -1; } static context_map_t * find_in_table(context_map_node_t **table, const char *key) { unsigned int bucket = hash(key) % N_BUCKETS; context_map_node_t **n; for (n = &table[bucket]; *n; n = &(*n)->next) if (!strcmp((*n)->key, key)) return (*n)->map; return NULL; } char * trim(char *str, const char *whitespace) { char *p = str + strlen(str); while (p > str && strchr(whitespace, *(p-1)) != NULL) *--p = 0; return str; } char * triml(char *str, const char *whitespace) { char *p = str; while (*p && (strchr(whitespace, *p) != NULL)) p++; return p; } int update(char **p, char *const val) { free (*p); *p = strdup(val); if (!*p) { log_error("allocation error %s", strerror(errno)); return -1; } return 0; } int append(affix_t **affixes, const char *val) { affix_t *affix = calloc(1, sizeof(affix_t)); if (!affix) { goto err; } affix->text = strdup(val); if (!affix->text) goto err; for (;*affixes; affixes = &(*affixes)->next) ; *affixes = affix; return 0; err: log_error("allocation error %s", strerror(errno)); return -1; } static int read_translations(const char *filename); /* Process line from translation file. Remove white space and set raw do data before the "=" and tok to data after it Modifies the data pointed to by the buffer parameter */ static int process_trans(char *buffer) { static domain_t *domain; static word_group_t *group; static int base_classification; static int lineno = 0; char op='\0'; lineno++; log_debug("%d: %s", lineno, buffer); /* zap leading whitespace */ buffer = triml(buffer, "\t "); /* Ignore comments */ if (*buffer == '#') return 0; char *comment = strpbrk (buffer, "#"); if (comment) { *comment = '\0'; } /* zap trailing whitespace */ buffer = trim(buffer, "\t \r\n"); if (*buffer == 0) return 0; char *delim = strpbrk (buffer, "=!>"); if (! delim) { syslog(LOG_ERR, "invalid line (no !, = or >) %d", lineno); return -1; } op = *delim; *delim = '\0'; char *raw = buffer; char *tok = delim+1; /* remove trailing/leading whitespace from the split tokens */ trim(raw, "\t "); tok = triml(tok, "\t "); if (! *raw) { syslog(LOG_ERR, "invalid line %d", lineno); return -1; } if (! *tok) { syslog(LOG_ERR, "invalid line %d", lineno); return -1; } /* constraints have different syntax */ if (op == '!' || op == '>') { return add_constraint(op, raw, tok); } if (!strcmp(raw, "Domain")) { domain = create_domain(tok); group = NULL; return 0; } if (!domain) { domain = create_domain("Default"); if (!domain) return -1; group = NULL; } if (!group && (!strcmp(raw, "Whitespace") || !strcmp(raw, "Join") || !strcmp(raw, "Prefix") || !strcmp(raw, "Suffix") || !strcmp(raw, "Default"))) { syslog(LOG_ERR, "expected ModifierGroup declaration on line %d", lineno); return -1; } if (!strcmp(raw, "Include")) { unsigned int n; glob_t g; g.gl_offs = 0; if (glob(tok, GLOB_ERR, NULL, &g) < 0) { globfree(&g); return -1; } for (n=0; n < g.gl_pathc; n++) { if (read_translations(g.gl_pathv[n]) < 0) { globfree(&g); return -1; } } globfree(&g); } else if (!strcmp(raw, "Base")) { base_classification = 1; } else if (!strcmp(raw, "ModifierGroup")) { group = create_group(&domain->groups, tok); if (!group) return -1; base_classification = 0; } else if (!strcmp(raw, "Whitespace")) { if (update (&group->whitespace, tok) < 0) return -1; } else if (!strcmp(raw, "Join")) { if (update (&group->join, tok) < 0) return -1; } else if (!strcmp(raw, "Prefix")) { if (append (&group->prefixes, tok) < 0) return -1; } else if (!strcmp(raw, "Suffix")) { if (append (&group->suffixes, tok) < 0) return -1; } else if (!strcmp(raw, "Default")) { ebitmap_t empty; ebitmap_init(&empty); if (parse_ebitmap(&group->def, &empty, tok) < 0) { syslog(LOG_ERR, "unable to parse Default %d", lineno); return -1; } } else if (group) { if (add_word(group, raw, tok) < 0) { syslog(LOG_ERR, "unable to add base_classification on line %d", lineno); return -1; } } else { if (base_classification) { if (add_base_classification(domain, raw, tok) < 0) { syslog(LOG_ERR, "unable to add base_classification on line %d", lineno); return -1; } } if (add_cache(domain, raw, tok) < 0) return -1; } return 0; } int read_translations(const char *filename) { size_t size = 0; char *buffer = NULL; int rval = 0; FILE *cfg = fopen(filename,"r"); if (!cfg) { syslog(LOG_ERR, "%s file open failed", filename); return -1; } __fsetlocking(cfg, FSETLOCKING_BYCALLER); while (getline(&buffer, &size, cfg) > 0) { if( process_trans(buffer) < 0 ) { syslog(LOG_ERR, "%s file read failed", filename); rval = -1; break; } } free(buffer); fclose(cfg); return rval; } int init_translations(void) { if (is_selinux_mls_enabled() <= 0) return -1; return(read_translations(selinux_translations_path())); } char * extract_range(const security_context_t incon) { context_t con = context_new(incon); if (!con) { syslog(LOG_ERR, "extract_range context_new(%s) failed: %s", incon, strerror(errno)); return NULL; } const char *range = context_range_get(con); if (!range) { syslog(LOG_ERR, "extract_range: context_range_get(%s) failed: %m", incon); context_free(con); return NULL; } char *r = strdup(range); if (!r) { log_error("extract_range: allocation error %s", strerror(errno)); return NULL; } context_free(con); return r; } char * new_context_str(const security_context_t incon, const char *range) { char *rcon = NULL; context_t con = context_new(incon); if (!con) { goto exit; } context_range_set(con, range); rcon = strdup(context_str(con)); if (!rcon) { goto exit; } return rcon; exit: log_error("new_context_str: %s %s", incon, strerror(errno)); return NULL; } char * find_in_hashtable(const char *range, domain_t *domain, context_map_node_t **table) { char *trans = NULL; context_map_t *map = find_in_table(table, range); if (map) { trans = strdup((table == domain->raw_to_trans) ? map->trans: map->raw); if (!trans) { log_error("find_in_hashtable: allocation error %s", strerror(errno)); return NULL; } log_debug(" found %s in hashtable returning %s\n", range, trans); } return trans; } void emit_whitespace(char*buffer, char *whitespace) { strcat(buffer, "["); strcat(buffer, whitespace); strcat(buffer, "]"); } static int string_size(const void *p1, const void *p2) { return strlen(*(char **)p2) - strlen(*(char **)p1); } static int word_size(const void *p1, const void *p2) { word_t *w1 = *(word_t **)p1; word_t *w2 = *(word_t **)p2; int w1_len=strlen(w1->text); int w2_len=strlen(w2->text); if (w1_len == w2_len) return strcmp(w1->text, w2->text); return (w2_len - w1_len); } void build_regexp(pcre **r, char *buffer) { const char *error; int error_offset; if (*r) pcre_free(*r); *r = pcre_compile(buffer, PCRE_CASELESS, &error, &error_offset, NULL); if (error) { log_error("pcre=%s, error=%s\n", buffer, error ? error: "none"); } buffer[0] = '\0'; } int build_regexps(domain_t *domain) { char buffer[1024 * 128]; buffer[0] = '\0'; base_classification_t *bc; word_group_t *g; affix_t *a; word_t *w; size_t n_el, i; for (n_el = 0, bc = domain->base_classifications; bc; bc = bc->next) { n_el++; } char **sortable = calloc(n_el, sizeof(char *)); if (!sortable) { log_error("allocation error %s", strerror(errno)); return -1; } for (i=0, bc = domain->base_classifications; bc; bc = bc->next) { sortable[i++] = bc->trans; } qsort(sortable, n_el, sizeof(char *), string_size); for (i = 0; i < n_el; i++) { strcat(buffer, sortable[i]); if (i < n_el) strcat(buffer,"|"); } free(sortable); log_debug(">>> %s classification regexp=%s\n", domain->name, buffer); build_regexp(&domain->base_classification_regexp, buffer); for (g = domain->groups; g; g = g->next) { if (g->prefixes) { strcat(buffer,"(?:"); for (a = g->prefixes; a; a = a->next) { strcat(buffer, a->text); if (a->next) strcat(buffer,"|"); } strcat(buffer,")"); strcat(buffer,"[ ]+"); log_debug(">>> %s %s prefix regexp=%s\n", domain->name, g->name, buffer); build_regexp(&g->prefix_regexp, buffer); } if (g->prefixes) strcat(buffer, "^"); strcat(buffer, "(?:"); g->sword_len=0; for (w = g->words; w; w = w->next) g->sword_len++; g->sword = calloc(g->sword_len, sizeof(word_t *)); if (!g->sword) { log_error("allocation error %s", strerror(errno)); return -1; } int i=0; for (w = g->words; w; w = w->next) g->sword[i++]=w; qsort(g->sword, g->sword_len, sizeof(word_t *), word_size); for (i=0; i < g->sword_len; i++) { if (i) strcat(buffer,"|"); strcat(buffer,"\\b"); strcat(buffer, g->sword[i]->text); strcat(buffer,"\\b"); } if (g->whitespace) { strcat(buffer,"|["); strcat(buffer, g->whitespace); strcat(buffer, "]+"); } strcat(buffer, ")+"); if (g->suffixes) strcat(buffer, "$"); log_debug(">>> %s %s modifier regexp=%s\n", domain->name, g->name, buffer); build_regexp(&g->word_regexp, buffer); if (g->suffixes) { strcat(buffer,"[ ]+"); strcat(buffer,"(?:"); for (a = g->suffixes; a; a = a->next) { strcat(buffer, a->text); if (a->next) strcat(buffer,"|"); } strcat(buffer,")"); log_debug(">>> %s %s suffix regexp=%s\n", domain->name, g->name, buffer); build_regexp(&g->suffix_regexp, buffer); } } return 0; } char * compute_raw_from_trans(const char *level, domain_t *domain) { #ifdef DEBUG struct timeval startTime; gettimeofday(&startTime, 0); #endif int ovector[OVECCOUNT]; word_group_t *g = NULL; char *work = NULL; char *r = NULL; const char * match = NULL; int work_len; mls_level_t *mraw = NULL; ebitmap_t set, clear, tmp; ebitmap_init(&set); ebitmap_init(&clear); ebitmap_init(&tmp); work = strdup(level); if (!work) { log_error("compute_raw_from_trans: allocation error %s", strerror(errno)); goto err; } work_len = strlen(work); if (!domain->base_classification_regexp) if (build_regexps(domain) < 0) goto err; if (!domain->base_classification_regexp) goto err; log_debug(" compute_raw_from_trans work = %s\n", work); int rc = pcre_exec(domain->base_classification_regexp, 0, work, work_len, 0, PCRE_ANCHORED, ovector, OVECCOUNT); if (rc > 0) { match = NULL; pcre_get_substring(work, ovector, rc, 0, &match); log_debug(" compute_raw_from_trans match = %s len = %u\n", match, strlen(match)); base_classification_t *bc; for (bc = domain->base_classifications; bc; bc = bc->next) { if (!strcmp(bc->trans, match)) { log_debug(" compute_raw_from_trans base classification %s matched %s\n", level, bc->trans); mraw = malloc(sizeof(mls_level_t)); if (!mraw) { log_error("allocation error %s", strerror(errno)); goto err; } if (mls_level_cpy(mraw, bc->level) < 0) goto err; break; } } memset(work + ovector[0], '#', ovector[1] - ovector[0]); char *p=work + ovector[0] + ovector[1]; while (*p && (strchr(" ", *p) != NULL)) *p++ = '#'; pcre_free((char *)match); match = NULL; } else { log_debug(" compute_raw_from_trans no base classification matched %s\n", level); } if (mraw == NULL) { goto err; } int complete = 0; int change = 1; while(change && !complete) { change = 0; for (g = domain->groups; g && !change && !complete; g = g->next) { int prefix = 0, suffix = 0; int prefix_offset = 0, prefix_len = 0; int suffix_offset = 0, suffix_len = 0; if (g->prefix_regexp) { int rc = pcre_exec(g->prefix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT); if (rc > 0) { prefix = 1; prefix_offset = ovector[0]; prefix_len = ovector[1] - ovector[0]; } } if (g->suffix_regexp) { int rc = pcre_exec(g->suffix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT); if (rc > 0) { suffix = 1; suffix_offset = ovector[0]; suffix_len = ovector[1] - ovector[0]; } } /* anchors prefix ^, suffix $ */ if (((!g->prefixes && !g->suffixes) || (g->prefixes && prefix) || (g->suffixes && suffix)) && g->word_regexp) { char *s = work + prefix_offset + prefix_len; int l = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset; int rc = pcre_exec(g->word_regexp, 0, s, l, 0, 0, ovector, OVECCOUNT); if (rc > 0) { match = NULL; pcre_get_substring(s, ovector, rc, 0, &match); trim((char *)match, g->whitespace); if (*match) { char *p = triml((char *)match, g->whitespace); while (p && *p) { int plen = strlen(p); int i; for (i = 0; i < g->sword_len; i++) { word_t *w = g->sword[i]; int wlen = strlen(w->text); if (plen >= wlen && !strncmp(w->text, p, strlen(w->text))){ if (ebitmap_andnot(&set, &w->cat, &g->def, maxbit) < 0) goto err; if (ebitmap_xor(&tmp, &w->cat, &g->def) < 0) goto err; if (ebitmap_and(&clear, &tmp, &g->def) < 0) goto err; if (ebitmap_union(&mraw->cat, &set) < 0) goto err; ebitmap_destroy(&tmp); if (ebitmap_cpy(&tmp, &mraw->cat) < 0) goto err; ebitmap_destroy(&mraw->cat); if (ebitmap_andnot(&mraw->cat, &tmp, &clear, maxbit) < 0) goto err; ebitmap_destroy(&tmp); ebitmap_destroy(&set); ebitmap_destroy(&clear); p += strlen(w->text); change++; break; } } if (i == g->sword_len) { syslog(LOG_ERR, "conversion error"); break; } p = triml(p, g->whitespace); } memset(work + prefix_offset, '#', prefix_len); memset(work + suffix_offset, '#', suffix_len); memset(s + ovector[0], '#', ovector[1] - ovector[0]); } pcre_free((void *)match); match = NULL; } } /* YYY */ complete=1; char *p = work; while(*p) { if (isalnum(*p++)) { complete=0; break; } } } } free(work); if (violates_constraints(mraw)) { complete = 0; } if (complete) r = mls_level_to_string(mraw); mls_level_destroy(mraw); free(mraw); #ifdef DEBUG struct timeval stopTime; gettimeofday(&stopTime, 0); long int ms; if (startTime.tv_usec > stopTime.tv_usec) ms = (stopTime.tv_sec - startTime.tv_sec - 1) * 1000 + (stopTime.tv_usec/1000 + 1000 - startTime.tv_usec/1000); else ms = (stopTime.tv_sec - startTime.tv_sec ) * 1000 + (stopTime.tv_usec/1000 - startTime.tv_usec/1000); log_debug(" compute_raw_from_trans in %ld ms'\n", ms); #endif return r; err: mls_level_destroy(mraw); free(mraw); free(work); pcre_free((void *)match); ebitmap_destroy(&tmp); ebitmap_destroy(&set); ebitmap_destroy(&clear); return NULL; } char * compute_trans_from_raw(const char *level, domain_t *domain) { #ifdef DEBUG struct timeval startTime; gettimeofday(&startTime, 0); #endif mls_level_t *l = NULL; char *rval = NULL; ebitmap_t bit_diff, temp, handled, nothandled, unhandled, orig_unhandled; ebitmap_init(&bit_diff); ebitmap_init(&temp); ebitmap_init(&handled); ebitmap_init(¬handled); ebitmap_init(&unhandled); ebitmap_init(&orig_unhandled); if (!level) goto err; l = parse_raw(level); if (!l) goto err; log_debug(" compute_trans_from_raw raw = %s\n", level); /* YYY */ /* check constraints */ if (violates_constraints(l)) { syslog(LOG_ERR, "%s violates constraints", level); goto err; } int doInverse = l->sens > 0; word_group_t *groups = NULL; base_classification_t *bc, *last = NULL; int done = 0; for (bc = domain->base_classifications; bc && !done; bc = bc->next) { if (l->sens == bc->level->sens) { /* skip if alias of last bc */ if (last && last->level->sens == bc->level->sens && ebitmap_cmp(&last->level->cat, &bc->level->cat) == 0) continue; /* compute bits not consumed by base classification */ ebitmap_t unhandled, orig_unhandled; if (ebitmap_xor(&unhandled, &l->cat, &bc->level->cat) < 0) goto err; if (ebitmap_cpy(&orig_unhandled, &unhandled) < 0) goto err; /* prebuild groups */ word_group_t *g; for (g = domain->groups; g; g = g->next) { word_group_t **t; for (t = &groups; *t; t = &(*t)->next) if (!strcmp(g->name, (*t)->name)) break; if (! *t) { word_group_t *wg = create_group(&groups, g->name); if (g->prefixes) if (append(&wg->prefixes, g->prefixes->text) < 0) goto err; if (g->suffixes) if (append(&wg->suffixes, g->suffixes->text) < 0) goto err; if (g->join) if (update(&wg->join, g->join) < 0) goto err; } } int loops, hamming, change=1; for (loops = 50; ebitmap_cardinality(&unhandled) && loops > 0 && change; loops--) { change = 0; hamming = 10000; ebitmap_t handled, nothandled; if (ebitmap_xor(&handled, &unhandled, &orig_unhandled) < 0) goto err; if (ebitmap_not(¬handled, &handled, maxbit) < 0) goto err; word_group_t *currentGroup = NULL; word_t *currentWord = NULL; for (g = domain->groups; g && hamming; g = g->next) { word_t *w; for (w = g->words; w && hamming; w = w->next) { int cardinality = ebitmap_cardinality(&w->normal); /* If the word is all inverse bits and the level does not have inverse bits - skip */ if (cardinality && !doInverse) { continue; } /* if only unhandled bits are different */ ebitmap_t temp; ebitmap_t bit_diff; if (ebitmap_or(&temp, &w->normal, &w->inverse) < 0) goto err; if (ebitmap_and(&bit_diff, &temp, ¬handled) < 0) goto err; ebitmap_destroy(&temp); // xor bit_diff handled? if (ebitmap_and(&temp, &bit_diff, &unhandled) < 0) goto err; if (ebitmap_cmp(&bit_diff, &temp)) { int h = ebitmap_hamming_distance(&bit_diff, &unhandled); if (h < hamming) { hamming = h; currentGroup = g; currentWord = w; } } ebitmap_destroy(&bit_diff); ebitmap_destroy(&temp); } } ebitmap_destroy(&handled); ebitmap_destroy(¬handled); if (currentWord) { ebitmap_t bit_diff; if (ebitmap_xor(&bit_diff, ¤tWord->cat, &bc->level->cat) < 0) goto err; ebitmap_t temp; if (ebitmap_cpy(&temp, &unhandled) < 0) goto err; ebitmap_destroy(&unhandled); if (ebitmap_andnot(&unhandled, &temp, &bit_diff, maxbit) < 0) goto err; ebitmap_destroy(&bit_diff); ebitmap_destroy(&temp); word_group_t **t; for (t = &groups; *t; t = &(*t)->next) if (!strcmp(currentGroup->name, (*t)->name)) break; create_word(&(*t)->words, currentWord->text); change++; } } done = (ebitmap_cardinality(&unhandled) == 0); ebitmap_destroy(&unhandled); ebitmap_destroy(&orig_unhandled); if (done) { char buffer[9999]; buffer[0] = 0; strcat(buffer, bc->trans); strcat(buffer, " "); word_group_t *g; for (g=groups; g; g = g->next) { if (g->words && g->prefixes) { strcat(buffer, g->prefixes->text); strcat(buffer, " "); } word_t *w; for (w=g->words; w; w = w->next) { strcat(buffer, w->text); if (w->next) strcat(buffer, g->join); } if (g->words && g->suffixes) { strcat(buffer, " "); strcat(buffer, g->suffixes->text); } word_group_t *n = g->next; while(g->words && n) { if (n->words) { strcat(buffer, " "); break; } n = n->next; } } rval = strdup(buffer); if (!rval) { log_error("compute_trans_from_raw: allocation error %s", strerror(errno)); goto err; } } /* clean up */ while (groups) destroy_group(&groups, groups); } last = bc; } if (l) { mls_level_destroy(l); free(l); } #ifdef DEBUG struct timeval stopTime; gettimeofday(&stopTime, 0); long int ms; if (startTime.tv_usec > stopTime.tv_usec) ms = (stopTime.tv_sec - startTime.tv_sec - 1) * 1000 + (stopTime.tv_usec/1000 + 1000 - startTime.tv_usec/1000); else ms = (stopTime.tv_sec - startTime.tv_sec ) * 1000 + (stopTime.tv_usec/1000 - startTime.tv_usec/1000); log_debug(" compute_trans_from_raw in %ld ms'\n", ms); #endif return rval; err: while (groups) destroy_group(&groups, groups); mls_level_destroy(l); free(l); return NULL; } int trans_context(const security_context_t incon, security_context_t *rcon) { char *trans = NULL; *rcon = NULL; #ifdef DEBUG struct timeval startTime; gettimeofday(&startTime, 0); #endif log_debug(" trans_context input = %s\n", incon); char *range = extract_range(incon); if (!range) return -1; domain_t *domain = domains; for (;domain; domain = domain->next) { trans = find_in_hashtable(range, domain, domain->raw_to_trans); if (trans) break; /* try split and translate */ char *lrange = NULL, *urange = NULL; char *ltrans = NULL, *utrans = NULL; char *dashp = strchr(range,'-'); if (dashp) { *dashp = 0; lrange = range; urange = dashp+1; } else { trans = compute_trans_from_raw(range, domain); if (trans) if (add_cache(domain, range, trans) < 0) return -1; } if (lrange && urange) { ltrans = find_in_hashtable(lrange, domain, domain->raw_to_trans); if (! ltrans) { ltrans = compute_trans_from_raw(lrange, domain); if (ltrans) { if (add_cache(domain, lrange, ltrans) < 0) return -1; } else { ltrans = strdup(lrange); if (! ltrans) { log_error("strdup failed %s", strerror(errno)); return -1; } } } utrans = find_in_hashtable(urange, domain, domain->raw_to_trans); if (! utrans) { utrans = compute_trans_from_raw(urange, domain); if (utrans) { if (add_cache(domain, urange, utrans) < 0) return -1; } else { utrans = strdup(urange); if (! utrans) { log_error("strdup failed %s", strerror(errno)); return -1; } } } if (strcmp(ltrans, utrans) == 0) { if (asprintf(&trans, "%s", ltrans) < 0) { log_error("asprintf failed %s", strerror(errno)); return -1; } } else { if (asprintf(&trans, "%s-%s", ltrans, utrans) < 0) { log_error("asprintf failed %s", strerror(errno)); return -1; } } free(ltrans); free(utrans); *dashp = '-'; break; } if (dashp) *dashp = '-'; } if (trans) { *rcon = new_context_str(incon, trans); free(trans); } else { *rcon = new_context_str(incon, range); } free(range); #ifdef DEBUG struct timeval stopTime; gettimeofday(&stopTime, 0); long int ms; if (startTime.tv_usec > stopTime.tv_usec) ms = (stopTime.tv_sec - startTime.tv_sec - 1) * 1000 + (stopTime.tv_usec/1000 + 1000 - startTime.tv_usec/1000); else ms = (stopTime.tv_sec - startTime.tv_sec ) * 1000 + (stopTime.tv_usec/1000 - startTime.tv_usec/1000); log_debug(" trans_context input='%s' output='%s in %ld ms'\n", incon, *rcon, ms); #endif return 0; } int untrans_context(const security_context_t incon, security_context_t *rcon) { char *raw = NULL; *rcon = NULL; #ifdef DEBUG struct timeval startTime; gettimeofday(&startTime, 0); #endif log_debug(" untrans_context incon = %s\n", incon); char *range = extract_range(incon); if (!range) return -1; log_debug(" untrans_context range = %s\n", range); domain_t *domain = domains; for (;domain; domain = domain->next) { raw = find_in_hashtable(range, domain, domain->trans_to_raw); if (raw) break; /* try split and translate */ char *lrange = NULL, *urange = NULL; char *lraw = NULL, *uraw = NULL; char *dashp = strchr(range,'-'); if (dashp) { *dashp = 0; lrange = range; urange = dashp+1; } else { raw = compute_raw_from_trans(range, domain); if (raw) { char *canonical = find_in_hashtable(raw, domain, domain->raw_to_trans); if (!canonical) { canonical = compute_trans_from_raw(raw, domain); if (canonical && strcmp(canonical, range)) if (add_cache(domain, raw, canonical) < 0) return -1; } if (canonical) free(canonical); if (add_cache(domain, raw, range) < 0) return -1; } else { log_debug("untrans_context unable to compute raw context %s\n", range); } } if (lrange && urange) { lraw = find_in_hashtable(lrange, domain, domain->trans_to_raw); if (! lraw) { lraw = compute_raw_from_trans(lrange, domain); if (lraw) { char *canonical = find_in_hashtable(lraw, domain, domain->raw_to_trans); if (!canonical) { canonical = compute_trans_from_raw(lraw, domain); if (canonical) if (add_cache(domain, lraw, canonical) < 0) return -1; } if (canonical) free(canonical); if (add_cache(domain, lraw, lrange) < 0) return -1; } else { lraw = strdup(lrange); if (! lraw) { log_error("strdup failed %s", strerror(errno)); return -1; } } } uraw = find_in_hashtable(urange, domain, domain->trans_to_raw); if (! uraw) { uraw = compute_raw_from_trans(urange, domain); if (uraw) { char *canonical = find_in_hashtable(uraw, domain, domain->raw_to_trans); if (!canonical) { canonical = compute_trans_from_raw(uraw, domain); if (canonical) if (add_cache(domain, uraw, canonical) < 0) return -1; } if (canonical) free(canonical); if (add_cache(domain, uraw, urange) < 0) return -1; } else { uraw = strdup(urange); if (! uraw) { log_error("strdup failed %s", strerror(errno)); return -1; } } } if (strcmp(lraw, uraw) == 0) { if (asprintf(&raw, "%s", lraw) < 0) { log_error("asprintf failed %s", strerror(errno)); return -1; } } else { if (asprintf(&raw, "%s-%s", lraw, uraw) < 0) { log_error("asprintf failed %s", strerror(errno)); return -1; } } free(lraw); free(uraw); *dashp = '-'; break; } if (dashp) *dashp = '-'; } if (raw) { *rcon = new_context_str(incon, raw); free(raw); } else { *rcon = new_context_str(incon, range); } free(range); #ifdef DEBUG struct timeval stopTime; gettimeofday(&stopTime, 0); long int ms; if (startTime.tv_usec > stopTime.tv_usec) ms = (stopTime.tv_sec - startTime.tv_sec - 1) * 1000 + (stopTime.tv_usec/1000 + 1000 - startTime.tv_usec/1000); else ms = (stopTime.tv_sec - startTime.tv_sec ) * 1000 + (stopTime.tv_usec/1000 - startTime.tv_usec/1000); log_debug(" untrans_context input='%s' output='%s' n %ld ms\n", incon, *rcon, ms); #endif return 0; } void finish_context_translations(void) { while(domains) { domain_t *next = domains->next; destroy_domain(domains); domains = next; } while(sens_constraints) { sens_constraint_t *next = sens_constraints->next; destroy_sens_constraint(&sens_constraints, sens_constraints); sens_constraints = next; } while(cat_constraints) { cat_constraint_t *next = cat_constraints->next; destroy_cat_constraint(&cat_constraints, cat_constraints); cat_constraints = next; } } policycoreutils-2.3/mcstrans/src/mcstrans.h000066400000000000000000000005031233221606300212270ustar00rootroot00000000000000/* Copyright (c) 2006 Trusted Computer Solutions, Inc. */ #include extern int init_translations(void); extern void finish_context_translations(void); extern int trans_context(const security_context_t, security_context_t *); extern int untrans_context(const security_context_t, security_context_t *); policycoreutils-2.3/mcstrans/src/mcstrans.init000066400000000000000000000033611233221606300217500ustar00rootroot00000000000000#!/bin/bash # # mcstransd This starts and stops mcstransd # # chkconfig: - 08 87 # description: This starts the SELinux Context Translation System Daemon # # processname: /sbin/mcstransd # pidfile: /var/run/mcstransd.pid # # Return values according to LSB for all commands but status: # 0 - success # 1 - generic or unspecified error # 2 - invalid or excess argument(s) # 3 - unimplemented feature (e.g. "reload") # 4 - insufficient privilege # 5 - program is not installed # 6 - program is not configured # 7 - program is not running PATH=/sbin:/bin:/usr/bin:/usr/sbin prog="mcstransd" lockfile=/var/lock/subsys/$prog # Source function library. . /etc/init.d/functions # Allow anyone to run status if [ "$1" = "status" ] ; then status $prog RETVAL=$? exit $RETVAL fi # Check that we are root ... so non-root users stop here test $EUID = 0 || exit 4 # If selinux is not enabled, return success test -x /usr/sbin/selinuxenabled && /usr/sbin/selinuxenabled || exit 0 RETVAL=0 start(){ test -x /sbin/mcstransd || exit 5 echo -n $"Starting $prog: " if status $prog > /dev/null; then echo -n $"$prog: already running" failure echo return 1 fi unset HOME MAIL USER USERNAME daemon $prog "$EXTRAOPTIONS" RETVAL=$? echo if test $RETVAL = 0 ; then touch $lockfile fi return $RETVAL } stop(){ echo -n $"Stopping $prog: " killproc $prog RETVAL=$? echo rm -f $lockfile return $RETVAL } restart(){ stop start } condrestart(){ [ -e $lockfile ] && restart return 0 } # See how we were called. case "$1" in start) start ;; stop) stop ;; restart|force-reload) restart ;; condrestart) condrestart ;; *) echo $"Usage: $0 {start|stop|status|restart|force-reload|condrestart}" RETVAL=3 esac exit $RETVAL policycoreutils-2.3/mcstrans/src/mcstrans.service000066400000000000000000000002641233221606300224440ustar00rootroot00000000000000[Unit] Description=Translates SELinux MCS/MLS labels to human readable form ConditionSecurity=selinux [Service] ExecStart=/sbin/mcstransd -f [Install] WantedBy=multi-user.target policycoreutils-2.3/mcstrans/src/mcstransd.c000066400000000000000000000320171233221606300213730ustar00rootroot00000000000000/* Copyright (c) 2006 Trusted Computer Solutions, Inc. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mcstrans.h" #ifdef UNUSED #elif defined(__GNUC__) # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) #elif defined(__LCLINT__) # define UNUSED(x) /*@unused@*/ x #else # define UNUSED(x) x #endif #define SETRANS_UNIX_SOCKET "/var/run/setrans/.setrans-unix" #define SETRANS_INIT 1 #define RAW_TO_TRANS_CONTEXT 2 #define TRANS_TO_RAW_CONTEXT 3 #define RAW_CONTEXT_TO_COLOR 4 #define MAX_DATA_BUF 4096 #define MAX_DESCRIPTORS 8192 #ifdef DEBUG //#define log_debug(fmt, ...) syslog(LOG_DEBUG, fmt, __VA_ARGS__) #define log_debug(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) #else #define log_debug(fmt, ...) ; #endif extern int init_translations(void); extern void finish_context_translations(void); extern int trans_context(const security_context_t, security_context_t *); extern int untrans_context(const security_context_t, security_context_t *); extern int init_colors(void); extern void finish_context_colors(void); extern int raw_color(const security_context_t, char **); #define SETRANSD_PATHNAME "/sbin/mcstransd" /* name of program (for error messages) */ #define SETRANSD_PROGNAME "mcstransd" static int sockfd = -1; /* socket we are listening on */ static volatile int restart_daemon = 0; static void cleanup_exit(int ret) __attribute__ ((noreturn)); static void cleanup_exit(int ret) { finish_context_colors(); finish_context_translations(); if (sockfd >=0) (void)unlink(SETRANS_UNIX_SOCKET); log_debug("%s\n", "cleanup_exit"); exit(ret); } static void clean_exit(void); static __attribute__((noreturn)) void clean_exit(void) { log_debug("%s\n", "clean_exit"); cleanup_exit(0); } static int send_response(int fd, uint32_t function, char *data, int32_t ret_val) { struct iovec resp_hdr[3]; uint32_t data_size; struct iovec resp_data; ssize_t count; if (!data) data = ""; data_size = strlen(data) + 1; resp_hdr[0].iov_base = &function; resp_hdr[0].iov_len = sizeof(function); resp_hdr[1].iov_base = &data_size; resp_hdr[1].iov_len = sizeof(data_size); resp_hdr[2].iov_base = &ret_val; resp_hdr[2].iov_len = sizeof(ret_val); while (((count = writev(fd, resp_hdr, 3)) < 0) && (errno == EINTR)); if (count != (sizeof(function) + sizeof(data_size) + sizeof(ret_val))) { syslog(LOG_ERR, "Failed to write response header"); return -1; } resp_data.iov_base = data; resp_data.iov_len = data_size; while (((count = writev(fd, &resp_data, 1)) < 0) && (errno == EINTR)); if (count < 0 || (size_t)count != data_size) { syslog(LOG_ERR, "Failed to write response data"); return -1; } return ret_val; } static int get_peer_pid(int fd, pid_t *pid) { int ret; socklen_t size = sizeof(struct ucred); struct ucred peercred; /* get the context of the requesting process */ ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &size); if (ret < 0) { syslog(LOG_ERR, "Failed to get PID of client process"); return -1; } *pid = peercred.pid; return ret; } static int get_peer_con(int fd, char **peercon) { int ret; pid_t pid; ret = get_peer_pid(fd, &pid); if (ret) return -1; ret = getpidcon_raw(pid, peercon); if (ret) { syslog(LOG_ERR, "Failed to get context of client process (pid=%u)", pid); return -1; } return 0; } static int process_request(int fd, uint32_t function, char *data1, char *UNUSED(data2)) { int32_t result; char *out = NULL; char *peercon = NULL; int ret; ret = get_peer_con(fd, &peercon); if (ret) return ret; /* TODO: Check if MLS clearance (in peercon) dominates the MLS label * (in the request input). */ switch (function) { case SETRANS_INIT: result = 0; ret = send_response(fd, function, NULL, result); break; case RAW_TO_TRANS_CONTEXT: result = trans_context(data1, &out); ret = send_response(fd, function, out, result); break; case TRANS_TO_RAW_CONTEXT: result = untrans_context(data1, &out); ret = send_response(fd, function, out, result); break; case RAW_CONTEXT_TO_COLOR: result = raw_color(data1, &out); ret = send_response(fd, function, out, result); break; default: result = -1; ret = -1; break; } if (result) { pid_t pid = 0; get_peer_pid(fd, &pid); syslog(LOG_ERR, "Invalid request func=%d from=%u", function, pid); } free(out); freecon(peercon); return ret; } static int service_request(int fd) { struct iovec req_hdr[3]; uint32_t function; uint32_t data1_size; uint32_t data2_size; struct iovec req_data[2]; char *data1; char *data2; int ret; ssize_t count; req_hdr[0].iov_base = &function; req_hdr[0].iov_len = sizeof(function); req_hdr[1].iov_base = &data1_size; req_hdr[1].iov_len = sizeof(data1_size); req_hdr[2].iov_base = &data2_size; req_hdr[2].iov_len = sizeof(data2_size); while (((count = readv(fd, req_hdr, 3)) < 0) && (errno == EINTR)); if (count <= 0) { return 1; } if (count != (sizeof(function) + sizeof(data1_size) + sizeof(data2_size) )) { log_debug("Failed to read request header %d != %u\n",(int)count, (unsigned)(sizeof(function) + sizeof(data1_size) + sizeof(data2_size) )); return -1; } if (!data1_size || !data2_size || data1_size > MAX_DATA_BUF || data2_size > MAX_DATA_BUF ) { log_debug("Header invalid data1_size=%u data2_size=%u\n", data1_size, data2_size); return -1; } data1 = malloc(data1_size); if (!data1) { log_debug("Could not allocate %d bytes\n", data1_size); return -1; } data2 = malloc(data2_size); if (!data2) { free(data1); log_debug("Could not allocate %d bytes\n", data2_size); return -1; } req_data[0].iov_base = data1; req_data[0].iov_len = data1_size; req_data[1].iov_base = data2; req_data[1].iov_len = data2_size; while (((count = readv(fd, req_data, 2)) < 0) && (errno == EINTR)); if (count <= 0 || (size_t)count != (data1_size + data2_size) || data1[data1_size - 1] != '\0' || data2[data2_size - 1] != '\0') { free(data1); free(data2); log_debug("Failed to read request data (%d)\n", (int)count); return -1; } ret = process_request(fd, function, data1, data2); free(data1); free(data2); return ret; } static int add_pollfd(struct pollfd **ufds, int *nfds, int connfd) { int ii = 0; /* First see if we can find an already invalidated ufd */ for (ii = 0; ii < *nfds; ii++) { if ((*ufds)[ii].fd == -1) break; } if (ii == *nfds) { struct pollfd *tmp = (struct pollfd *)realloc(*ufds, (*nfds+1)*sizeof(struct pollfd)); if (!tmp) { syslog(LOG_ERR, "realloc failed for %d fds", *nfds+1); return -1; } *ufds = tmp; (*nfds)++; } (*ufds)[ii].fd = connfd; (*ufds)[ii].events = POLLIN|POLLPRI; (*ufds)[ii].revents = 0; return 0; } static void adj_pollfds(struct pollfd **ufds, int *nfds) { int ii, jj; jj = 0; for (ii = 0; ii < *nfds; ii++) { if ((*ufds)[ii].fd != -1) { if (jj < ii) (*ufds)[jj] = (*ufds)[ii]; jj++; } } *nfds = jj; } static int process_events(struct pollfd **ufds, int *nfds) { int ii = 0; int ret = 0; for (ii = 0; ii < *nfds; ii++) { short revents = (*ufds)[ii].revents; int connfd = (*ufds)[ii].fd; if (revents & (POLLIN | POLLPRI)) { if (connfd == sockfd) { /* Probably received a connection */ if ((connfd = accept(sockfd, NULL, NULL)) < 0) { syslog(LOG_ERR, "accept() failed: %m"); return -1; } if (add_pollfd(ufds, nfds, connfd)) { syslog(LOG_ERR, "Failed to add fd (%d) to poll list\n", connfd); return -1; } } else { ret = service_request(connfd); if (ret) { if (ret < 0) { syslog(LOG_ERR, "Servicing of request " "failed for fd (%d)\n", connfd); } /* Setup pollfd for deletion later. */ (*ufds)[ii].fd = -1; close(connfd); /* So we don't get bothered later */ revents = revents & ~(POLLHUP); } } revents = revents & ~(POLLIN | POLLPRI); } if (revents & POLLHUP) { log_debug("The connection with fd (%d) hung up\n", connfd); /* Set the pollfd up for deletion later. */ (*ufds)[ii].fd = -1; close(connfd); revents = revents & ~(POLLHUP); } if (revents) { syslog(LOG_ERR, "Unknown/error events (%x) encountered" " for fd (%d)\n", revents, connfd); /* Set the pollfd up for deletion later. */ (*ufds)[ii].fd = -1; close(connfd); } (*ufds)[ii].revents = 0; } /* Delete any invalidated ufds */ adj_pollfds(ufds, nfds); return 0; } static void process_connections(void) __attribute__ ((noreturn)); static void process_connections(void) { int ret = 0; int nfds = 1; struct pollfd *ufds = (struct pollfd *)malloc(sizeof(struct pollfd)); if (!ufds) { syslog(LOG_ERR, "Failed to allocate a pollfd"); cleanup_exit(1); } ufds[0].fd = sockfd; ufds[0].events = POLLIN|POLLPRI; ufds[0].revents = 0; while (1) { if (restart_daemon) { syslog(LOG_NOTICE, "Reload Translations"); finish_context_colors(); finish_context_translations(); if (init_translations()) { syslog(LOG_ERR, "Failed to initialize label translations"); cleanup_exit(1); } if (init_colors()) { syslog(LOG_ERR, "Failed to initialize color translations"); syslog(LOG_ERR, "No color information will be available"); } restart_daemon = 0; } ret = poll(ufds, nfds, -1); if (ret < 0) { if (errno == EINTR) { continue; } syslog(LOG_ERR, "poll() failed: %m"); cleanup_exit(1); } ret = process_events(&ufds, &nfds); if (ret) { syslog(LOG_ERR, "Error processing events"); cleanup_exit(1); } } } static void sigterm_handler(int sig) __attribute__ ((noreturn)); static void sigterm_handler(int UNUSED(sig)) { cleanup_exit(0); } static void sighup_handler(int UNUSED(sig)) { restart_daemon = 1; } static void initialize(void) { struct sigaction act; struct sockaddr_un addr; struct rlimit rl ; if (init_translations()) { syslog(LOG_ERR, "Failed to initialize label translations"); cleanup_exit(1); } if (init_colors()) { syslog(LOG_ERR, "Failed to initialize color translations"); syslog(LOG_ERR, "No color information will be available"); } /* the socket will be unlinked when the daemon terminates */ act.sa_handler = sigterm_handler; sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGINT); sigaddset(&act.sa_mask, SIGQUIT); sigaddset(&act.sa_mask, SIGTERM); sigaddset(&act.sa_mask, SIGHUP); act.sa_flags = 0; sigaction(SIGINT, &act, NULL); sigaction(SIGQUIT, &act, NULL); sigaction(SIGTERM, &act, NULL); /* restart the daemon on SIGHUP */ act.sa_handler = sighup_handler; sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGINT); sigaddset(&act.sa_mask, SIGQUIT); sigaddset(&act.sa_mask, SIGTERM); act.sa_flags = 0; sigaction(SIGHUP, &act, NULL); /* ignore SIGPIPE (in case a client terminates after sending request) */ act.sa_handler = SIG_IGN; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGPIPE, &act, NULL); atexit(clean_exit); sockfd = socket(PF_UNIX, SOCK_STREAM, 0); if (sockfd < 0) { syslog(LOG_ERR, "socket() failed: %m"); cleanup_exit(1); } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SETRANS_UNIX_SOCKET, sizeof(addr.sun_path) - 1); (void)unlink(SETRANS_UNIX_SOCKET); if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { syslog(LOG_ERR, "bind() failed: %m"); cleanup_exit(1); } if (listen(sockfd, SOMAXCONN) < 0) { syslog(LOG_ERR, "listen() failed: %m"); cleanup_exit(1); } if (chmod(SETRANS_UNIX_SOCKET, S_IRWXU | S_IRWXG | S_IRWXO)) { syslog(LOG_ERR, "chmod() failed: %m"); cleanup_exit(1); } /* Raise the rlimit for file descriptors... */ rl.rlim_max = MAX_DESCRIPTORS; rl.rlim_cur = MAX_DESCRIPTORS; setrlimit(RLIMIT_NOFILE, &rl); } void dropprivs(void) { cap_t new_caps; new_caps = cap_init(); if (cap_set_proc(new_caps)) { syslog(LOG_ERR, "Error dropping capabilities, aborting: %s\n", strerror(errno)); cleanup_exit(-1); } cap_free(new_caps); } static void usage(char *program) { printf("%s [-f] [-h] \n", program); } int main(int argc, char *argv[]) { int opt; int do_fork = 1; while ((opt = getopt(argc, argv, "hf")) > 0) { switch (opt) { case 'f': do_fork = 0; break; case 'h': usage(argv[0]); exit(0); break; case '?': usage(argv[0]); exit(-1); } } #ifndef DEBUG /* Make sure we are root */ if (getuid() != 0) { syslog(LOG_ERR, "You must be root to run this program.\n"); return 4; } #endif openlog(SETRANSD_PROGNAME, 0, LOG_DAEMON); syslog(LOG_NOTICE, "%s starting", argv[0]); initialize(); #ifndef DEBUG dropprivs(); /* run in the background as a daemon */ if (do_fork && daemon(0, 0)) { syslog(LOG_ERR, "daemon() failed: %m"); cleanup_exit(1); } #endif syslog(LOG_NOTICE, "%s initialized", argv[0]); process_connections(); /* we should never get here */ return 1; } policycoreutils-2.3/mcstrans/src/mls_level.c000066400000000000000000000057431233221606300213650ustar00rootroot00000000000000#include #include "mls_level.h" #include mls_level_t *mls_level_from_string(char *mls_context) { char delim; char *scontextp, *p, *lptr; mls_level_t *l; if (!mls_context) { return NULL; } l = (mls_level_t *) calloc(1, sizeof(mls_level_t)); /* Extract low sensitivity. */ scontextp = p = mls_context; while (*p && *p != ':' && *p != '-') p++; delim = *p; if (delim != 0) *p++ = 0; if (*scontextp != 's') goto err; l->sens = atoi(scontextp + 1); if (delim == ':') { /* Extract category set. */ while (1) { scontextp = p; while (*p && *p != ',' && *p != '-') p++; delim = *p; if (delim != 0) *p++ = 0; /* Separate into level if exists */ if ((lptr = strchr(scontextp, '.')) != NULL) { /* Remove '.' */ *lptr++ = 0; } if (*scontextp != 'c') goto err; int bit = atoi(scontextp + 1); if (ebitmap_set_bit(&l->cat, bit, 1)) goto err; /* If level, set all categories in level */ if (lptr) { if (*lptr != 'c') goto err; int ubit = atoi(lptr + 1); int i; for (i = bit + 1; i <= ubit; i++) { if (ebitmap_set_bit (&l->cat, i, 1)) goto err; } } if (delim != ',') break; } } return l; err: free(l); return NULL; } /* * Return the length in bytes for the MLS fields of the * security context string representation of `context'. */ unsigned int mls_compute_string_len(mls_level_t *l) { unsigned int len = 0; char temp[16]; unsigned int i, level = 0; ebitmap_node_t *cnode; if (!l) return 0; len += snprintf(temp, sizeof(temp), "s%d", l->sens); ebitmap_for_each_bit(&l->cat, cnode, i) { if (ebitmap_node_get_bit(cnode, i)) { if (level) { level++; continue; } len++; /* : or ,` */ len += snprintf(temp, sizeof(temp), "c%d", i); level++; } else { if (level > 1) len += snprintf(temp, sizeof(temp), ".c%d", i-1); level = 0; } } /* Handle case where last category is the end of level */ if (level > 1) len += snprintf(temp, sizeof(temp), ".c%d", i-1); return len; } char *mls_level_to_string(mls_level_t *l) { unsigned int wrote_sep, len = mls_compute_string_len(l); unsigned int i, level = 0; ebitmap_node_t *cnode; wrote_sep = 0; if (len == 0) return NULL; char *result = (char *)malloc(len + 1); char *p = result; p += sprintf(p, "s%d", l->sens); /* categories */ ebitmap_for_each_bit(&l->cat, cnode, i) { if (ebitmap_node_get_bit(cnode, i)) { if (level) { level++; continue; } if (!wrote_sep) { *p++ = ':'; wrote_sep = 1; } else *p++ = ','; p += sprintf(p, "c%d", i); level++; } else { if (level > 1) { if (level > 2) *p++ = '.'; else *p++ = ','; p += sprintf(p, "c%d", i-1); } level = 0; } } /* Handle case where last category is the end of level */ if (level > 1) { if (level > 2) *p++ = '.'; else *p++ = ','; p += sprintf(p, "c%d", i-1); } *(result + len) = 0; return result; } policycoreutils-2.3/mcstrans/src/mls_level.h000066400000000000000000000003671233221606300213670ustar00rootroot00000000000000#ifndef __mls_level_h__ #define __mls_level_h__ #include unsigned int mls_compute_string_len(mls_level_t *r); mls_level_t *mls_level_from_string(char *mls_context); char *mls_level_to_string(mls_level_t *r); #endif policycoreutils-2.3/mcstrans/utils/000077500000000000000000000000001233221606300175775ustar00rootroot00000000000000policycoreutils-2.3/mcstrans/utils/Makefile000066400000000000000000000014561233221606300212450ustar00rootroot00000000000000# Installation directories. PREFIX ?= $(DESTDIR)/usr BINDIR ?= $(PREFIX)/sbin ARCH = $(shell uname -i) ifeq "$(ARCH)" "x86_64" # In case of 64 bit system, use these lines LIBDIR=/usr/lib64 else ifeq "$(ARCH)" "i686" # In case of 32 bit system, use these lines LIBDIR=/usr/lib else ifeq "$(ARCH)" "i386" # In case of 32 bit system, use these lines LIBDIR=/usr/lib endif endif endif CFLAGS ?= -Wall override CFLAGS += -I../src -D_GNU_SOURCE LDLIBS += -L../src ../src/mcstrans.o ../src/mls_level.o -lselinux -lpcre $(LIBDIR)/libsepol.a TARGETS=$(patsubst %.c,%,$(wildcard *.c)) all: $(TARGETS) install: all -mkdir -p $(BINDIR) install -m 755 $(TARGETS) $(BINDIR) test: ./mlstrans-test-runner.py ../test/*.test clean: rm -f $(TARGETS) *.o *~ \#* relabel: policycoreutils-2.3/mcstrans/utils/callgrind-mcstransd000066400000000000000000000003171233221606300234560ustar00rootroot00000000000000#!/bin/bash service mcstrans stop cd ~root runcon -u system_u -r system_r -t setrans_t -l s15:c0.c1023 -- valgrind --tool=callgrind /usr/src/redhat/BUILD/*/src/mcstransd run_init /etc/init.d/mcstrans start policycoreutils-2.3/mcstrans/utils/transcon.c000066400000000000000000000010321233221606300215660ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "mcstrans.h" void usage(const char *progname) { fprintf(stderr, "usage: %s context\n", progname); exit(1); } int main(int argc, char **argv) { security_context_t scon; if ( argc != 2 ) usage(argv[0]); if (init_translations()==0) { if(trans_context(argv[1],&scon) == 0) { printf("%s\n", scon); freecon(scon); return 0; } } printf("Failed\n"); return -1; } policycoreutils-2.3/mcstrans/utils/untranscon.c000066400000000000000000000010061233221606300221320ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "mcstrans.h" void usage(const char *progname) { fprintf(stderr, "usage: %s context\n", progname); exit(1); } int main(int argc, char **argv) { security_context_t scon; if ( argc != 2 ) usage(argv[0]); if (init_translations()==0) { if(untrans_context(argv[1],&scon) == 0) { printf("%s\n", scon); freecon(scon); return 0; } } return -1; } policycoreutils-2.3/mcstrans/utils/valgrind-mcstransd000066400000000000000000000004161233221606300233250ustar00rootroot00000000000000#!/bin/bash service mcstrans stop #valgrind -v --leak-check=full --show-reachable=yes ../src/mcstransd runcon -u system_u -r system_r -t setrans_t -l s15:c0.c1023 -- valgrind -v --leak-check=full --show-reachable=yes ../src/mcstransd run_init /etc/init.d/mcstrans start policycoreutils-2.3/newrole/000077500000000000000000000000001233221606300162605ustar00rootroot00000000000000policycoreutils-2.3/newrole/Makefile000066400000000000000000000047041233221606300177250ustar00rootroot00000000000000# Installation directories. PREFIX ?= $(DESTDIR)/usr BINDIR ?= $(PREFIX)/bin MANDIR ?= $(PREFIX)/share/man ETCDIR ?= $(DESTDIR)/etc LOCALEDIR = /usr/share/locale PAMH = $(shell ls /usr/include/security/pam_appl.h 2>/dev/null) AUDITH = $(shell ls /usr/include/libaudit.h 2>/dev/null) # Enable capabilities to permit newrole to generate audit records. # This will make newrole a setuid root program. # The capabilities used are: CAP_AUDIT_WRITE. AUDIT_LOG_PRIV ?= n # Enable capabilities to permit newrole to utilitize the pam_namespace module. # This will make newrole a setuid root program. # The capabilities used are: CAP_SYS_ADMIN, CAP_CHOWN, CAP_FOWNER and # CAP_DAC_OVERRIDE. NAMESPACE_PRIV ?= n # If LSPP_PRIV is y, then newrole will be made into setuid root program. # Enabling this option will force AUDIT_LOG_PRIV and NAMESPACE_PRIV to be y. LSPP_PRIV ?= n VERSION = $(shell cat ../VERSION) CFLAGS ?= -Werror -Wall -W EXTRA_OBJS = override CFLAGS += -DVERSION=\"$(VERSION)\" $(LDFLAGS) -I$(PREFIX)/include -DUSE_NLS -DLOCALEDIR="\"$(LOCALEDIR)\"" -DPACKAGE="\"policycoreutils\"" LDLIBS += -lselinux -L$(PREFIX)/lib ifeq ($(PAMH), /usr/include/security/pam_appl.h) override CFLAGS += -DUSE_PAM EXTRA_OBJS += hashtab.o LDLIBS += -lpam -lpam_misc else override CFLAGS += -D_XOPEN_SOURCE=500 LDLIBS += -lcrypt endif ifeq ($(AUDITH), /usr/include/libaudit.h) override CFLAGS += -DUSE_AUDIT LDLIBS += -laudit endif ifeq ($(LSPP_PRIV),y) override AUDIT_LOG_PRIV=y override NAMESPACE_PRIV=y endif ifeq ($(AUDIT_LOG_PRIV),y) override CFLAGS += -DAUDIT_LOG_PRIV IS_SUID=y endif ifeq ($(NAMESPACE_PRIV),y) override CFLAGS += -DNAMESPACE_PRIV IS_SUID=y endif ifeq ($(IS_SUID),y) MODE := 4555 LDLIBS += -lcap-ng else MODE := 0555 endif all: newrole newrole: newrole.o $(EXTRA_OBJS) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) install: all test -d $(BINDIR) || install -m 755 -d $(BINDIR) test -d $(ETCDIR)/pam.d || install -m 755 -d $(ETCDIR)/pam.d test -d $(MANDIR)/man1 || install -m 755 -d $(MANDIR)/man1 install -m $(MODE) newrole $(BINDIR) install -m 644 newrole.1 $(MANDIR)/man1/ ifeq ($(PAMH), /usr/include/security/pam_appl.h) test -d $(ETCDIR)/pam.d || install -m 755 -d $(ETCDIR)/pam.d ifeq ($(LSPP_PRIV),y) install -m 644 newrole-lspp.pamd $(ETCDIR)/pam.d/newrole else install -m 644 newrole.pamd $(ETCDIR)/pam.d/newrole endif endif clean: rm -f newrole *.o indent: ../../scripts/Lindent $(wildcard *.[ch]) relabel: install /sbin/restorecon $(BINDIR)/newrole policycoreutils-2.3/newrole/hashtab.c000066400000000000000000000130221233221606300200340ustar00rootroot00000000000000 /* Author : Stephen Smalley, */ /* FLASK */ /* * Implementation of the hash table type. */ #include #include #include "hashtab.h" hashtab_t hashtab_create(unsigned int (*hash_value) (hashtab_t h, const hashtab_key_t key), int (*keycmp) (hashtab_t h, const hashtab_key_t key1, const hashtab_key_t key2), unsigned int size) { hashtab_t p; unsigned int i; p = (hashtab_t) malloc(sizeof(hashtab_val_t)); if (p == NULL) return p; memset(p, 0, sizeof(hashtab_val_t)); p->size = size; p->nel = 0; p->hash_value = hash_value; p->keycmp = keycmp; p->htable = (hashtab_ptr_t *) malloc(sizeof(hashtab_ptr_t) * size); if (p->htable == NULL) { free(p); return NULL; } for (i = 0; i < size; i++) p->htable[i] = (hashtab_ptr_t) NULL; return p; } int hashtab_insert(hashtab_t h, hashtab_key_t key, hashtab_datum_t datum) { int hvalue; hashtab_ptr_t prev, cur, newnode; if (!h) return HASHTAB_OVERFLOW; hvalue = h->hash_value(h, key); prev = NULL; cur = h->htable[hvalue]; while (cur && h->keycmp(h, key, cur->key) > 0) { prev = cur; cur = cur->next; } if (cur && (h->keycmp(h, key, cur->key) == 0)) return HASHTAB_PRESENT; newnode = (hashtab_ptr_t) malloc(sizeof(hashtab_node_t)); if (newnode == NULL) return HASHTAB_OVERFLOW; memset(newnode, 0, sizeof(struct hashtab_node)); newnode->key = key; newnode->datum = datum; if (prev) { newnode->next = prev->next; prev->next = newnode; } else { newnode->next = h->htable[hvalue]; h->htable[hvalue] = newnode; } h->nel++; return HASHTAB_SUCCESS; } int hashtab_remove(hashtab_t h, hashtab_key_t key, void (*destroy) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args) { int hvalue; hashtab_ptr_t cur, last; if (!h) return HASHTAB_MISSING; hvalue = h->hash_value(h, key); last = NULL; cur = h->htable[hvalue]; while (cur != NULL && h->keycmp(h, key, cur->key) > 0) { last = cur; cur = cur->next; } if (cur == NULL || (h->keycmp(h, key, cur->key) != 0)) return HASHTAB_MISSING; if (last == NULL) h->htable[hvalue] = cur->next; else last->next = cur->next; if (destroy) destroy(cur->key, cur->datum, args); free(cur); h->nel--; return HASHTAB_SUCCESS; } int hashtab_replace(hashtab_t h, hashtab_key_t key, hashtab_datum_t datum, void (*destroy) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args) { int hvalue; hashtab_ptr_t prev, cur, newnode; if (!h) return HASHTAB_OVERFLOW; hvalue = h->hash_value(h, key); prev = NULL; cur = h->htable[hvalue]; while (cur != NULL && h->keycmp(h, key, cur->key) > 0) { prev = cur; cur = cur->next; } if (cur && (h->keycmp(h, key, cur->key) == 0)) { if (destroy) destroy(cur->key, cur->datum, args); cur->key = key; cur->datum = datum; } else { newnode = (hashtab_ptr_t) malloc(sizeof(hashtab_node_t)); if (newnode == NULL) return HASHTAB_OVERFLOW; memset(newnode, 0, sizeof(struct hashtab_node)); newnode->key = key; newnode->datum = datum; if (prev) { newnode->next = prev->next; prev->next = newnode; } else { newnode->next = h->htable[hvalue]; h->htable[hvalue] = newnode; } } return HASHTAB_SUCCESS; } hashtab_datum_t hashtab_search(hashtab_t h, const hashtab_key_t key) { int hvalue; hashtab_ptr_t cur; if (!h) return NULL; hvalue = h->hash_value(h, key); cur = h->htable[hvalue]; while (cur != NULL && h->keycmp(h, key, cur->key) > 0) cur = cur->next; if (cur == NULL || (h->keycmp(h, key, cur->key) != 0)) return NULL; return cur->datum; } void hashtab_destroy(hashtab_t h) { unsigned int i; hashtab_ptr_t cur, temp; if (!h) return; for (i = 0; i < h->size; i++) { cur = h->htable[i]; while (cur != NULL) { temp = cur; cur = cur->next; free(temp); } h->htable[i] = NULL; } free(h->htable); h->htable = NULL; free(h); } int hashtab_map(hashtab_t h, int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args) { unsigned int i, ret; hashtab_ptr_t cur; if (!h) return HASHTAB_SUCCESS; for (i = 0; i < h->size; i++) { cur = h->htable[i]; while (cur != NULL) { ret = apply(cur->key, cur->datum, args); if (ret) return ret; cur = cur->next; } } return HASHTAB_SUCCESS; } void hashtab_map_remove_on_error(hashtab_t h, int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), void (*destroy) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args) { unsigned int i; int ret; hashtab_ptr_t last, cur, temp; if (!h) return; for (i = 0; i < h->size; i++) { last = NULL; cur = h->htable[i]; while (cur != NULL) { ret = apply(cur->key, cur->datum, args); if (ret) { if (last) { last->next = cur->next; } else { h->htable[i] = cur->next; } temp = cur; cur = cur->next; if (destroy) destroy(temp->key, temp->datum, args); free(temp); h->nel--; } else { last = cur; cur = cur->next; } } } return; } void hashtab_hash_eval(hashtab_t h, char *tag) { unsigned int i; int chain_len, slots_used, max_chain_len; hashtab_ptr_t cur; slots_used = 0; max_chain_len = 0; for (i = 0; i < h->size; i++) { cur = h->htable[i]; if (cur) { slots_used++; chain_len = 0; while (cur) { chain_len++; cur = cur->next; } if (chain_len > max_chain_len) max_chain_len = chain_len; } } printf ("%s: %d entries and %d/%d buckets used, longest chain length %d\n", tag, h->nel, slots_used, h->size, max_chain_len); } policycoreutils-2.3/newrole/hashtab.h000066400000000000000000000105231233221606300200440ustar00rootroot00000000000000 /* Author : Stephen Smalley, */ /* FLASK */ /* * A hash table (hashtab) maintains associations between * key values and datum values. The type of the key values * and the type of the datum values is arbitrary. The * functions for hash computation and key comparison are * provided by the creator of the table. */ #ifndef _NEWROLE_HASHTAB_H_ #define _NEWROLE_HASHTAB_H_ #include #include #include typedef char *hashtab_key_t; /* generic key type */ typedef void *hashtab_datum_t; /* generic datum type */ typedef struct hashtab_node *hashtab_ptr_t; typedef struct hashtab_node { hashtab_key_t key; hashtab_datum_t datum; hashtab_ptr_t next; } hashtab_node_t; typedef struct hashtab_val { hashtab_ptr_t *htable; /* hash table */ unsigned int size; /* number of slots in hash table */ uint32_t nel; /* number of elements in hash table */ unsigned int (*hash_value) (struct hashtab_val * h, hashtab_key_t key); /* hash function */ int (*keycmp) (struct hashtab_val * h, hashtab_key_t key1, hashtab_key_t key2); /* key comparison function */ } hashtab_val_t; typedef hashtab_val_t *hashtab_t; /* Define status codes for hash table functions */ #define HASHTAB_SUCCESS 0 #define HASHTAB_OVERFLOW -ENOMEM #define HASHTAB_PRESENT -EEXIST #define HASHTAB_MISSING -ENOENT /* Creates a new hash table with the specified characteristics. Returns NULL if insufficent space is available or the new hash table otherwise. */ extern hashtab_t hashtab_create(unsigned int (*hash_value) (hashtab_t h, const hashtab_key_t key), int (*keycmp) (hashtab_t h, const hashtab_key_t key1, const hashtab_key_t key2), unsigned int size); /* Inserts the specified (key, datum) pair into the specified hash table. Returns HASHTAB_OVERFLOW if insufficient space is available or HASHTAB_PRESENT if there is already an entry with the same key or HASHTAB_SUCCESS otherwise. */ extern int hashtab_insert(hashtab_t h, hashtab_key_t k, hashtab_datum_t d); /* Removes the entry with the specified key from the hash table. Applies the specified destroy function to (key,datum,args) for the entry. Returns HASHTAB_MISSING if no entry has the specified key or HASHTAB_SUCCESS otherwise. */ extern int hashtab_remove(hashtab_t h, hashtab_key_t k, void (*destroy) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args); /* Insert or replace the specified (key, datum) pair in the specified hash table. If an entry for the specified key already exists, then the specified destroy function is applied to (key,datum,args) for the entry prior to replacing the entry's contents. Returns HASHTAB_OVERFLOW if insufficient space is available or HASHTAB_SUCCESS otherwise. */ extern int hashtab_replace(hashtab_t h, hashtab_key_t k, hashtab_datum_t d, void (*destroy) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args); /* Searches for the entry with the specified key in the hash table. Returns NULL if no entry has the specified key or the datum of the entry otherwise. */ extern hashtab_datum_t hashtab_search(hashtab_t h, const hashtab_key_t k); /* Destroys the specified hash table. */ extern void hashtab_destroy(hashtab_t h); /* Applies the specified apply function to (key,datum,args) for each entry in the specified hash table. The order in which the function is applied to the entries is dependent upon the internal structure of the hash table. If apply returns a non-zero status, then hashtab_map will cease iterating through the hash table and will propagate the error return to its caller. */ extern int hashtab_map(hashtab_t h, int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args); /* Same as hashtab_map, except that if apply returns a non-zero status, then the (key,datum) pair will be removed from the hashtab and the destroy function will be applied to (key,datum,args). */ extern void hashtab_map_remove_on_error(hashtab_t h, int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), void (*destroy) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args); extern void hashtab_hash_eval(hashtab_t h, char *tag); #endif policycoreutils-2.3/newrole/newrole-lspp.pamd000066400000000000000000000002541233221606300215530ustar00rootroot00000000000000#%PAM-1.0 auth include system-auth account include system-auth password include system-auth session required pam_namespace.so unmnt_remnt no_unmount_on_close policycoreutils-2.3/newrole/newrole.1000066400000000000000000000057741233221606300200320ustar00rootroot00000000000000.TH NEWROLE "1" "October 2000" "Security Enhanced Linux" NSA .SH NAME newrole \- run a shell with a new SELinux role .SH SYNOPSIS .B newrole [\fB-r\fR|\fB--role\fR] \fIROLE\fR [\fB-t\fR|\fB--type\fR] \fITYPE\fR [\fB-l\fR|\fB--level\fR] \fILEVEL\fR [-- [\fIARGS\fR]...] .SH DESCRIPTION .PP Run a new shell in a new context. The new context is derived from the old context in which .B newrole is originally executed. If the .B -r or .B --role option is specified, then the new context will have the role specified by \fIROLE\fR. If the .B -t or .B --type option is specified, then the new context will have the type (domain) specified by \fITYPE\fR. If a role is specified, but no type is specified, the default type is derived from the specified role. If the .B -l or .B --level option is specified, then the new context will have the sensitivity level specified by \fILEVEL\fR. If \fILEVEL\fR is a range, the new context will have the sensitivity level and clearance specified by that range. .PP Additional arguments .I ARGS may be provided after a -- option, in which case they are supplied to the new shell. In particular, an argument of \-\- \-c will cause the next argument to be treated as a command by most command interpreters. .PP If a command argument is specified to newrole and the command name is found in /etc/selinux/newrole_pam.conf, then the pam service name listed in that file for the command will be used rather than the normal newrole pam configuration. This allows for per-command pam configuration when invoked via newrole, e.g. to skip the interactive re-authentication phase. .PP The new shell will be the shell specified in the user's entry in the .I /etc/passwd file. .PP The .B -V or .B --version shows the current version of newrole .PP .SH EXAMPLE .br Changing role: # id \-Z staff_u:staff_r:staff_t:SystemLow-SystemHigh # newrole \-r sysadm_r # id \-Z staff_u:sysadm_r:sysadm_t:SystemLow-SystemHigh Changing sensitivity only: # id \-Z staff_u:sysadm_r:sysadm_t:Unclassified-SystemHigh # newrole \-l Secret # id \-Z staff_u:sysadm_r:sysadm_t:Secret-SystemHigh .PP Changing sensitivity and clearance: # id \-Z staff_u:sysadm_r:sysadm_t:Unclassified-SystemHigh # newrole \-l Secret-Secret # id \-Z staff_u:sysadm_r:sysadm_t:Secret .PP Running a program in a given role or level: # newrole \-r sysadm_r \-\- \-c "/path/to/app arg1 arg2..." # newrole \-l Secret \-\- \-c "/path/to/app arg1 arg2..." .SH FILES /etc/passwd - user account information .br /etc/shadow - encrypted passwords and age information .br /etc/selinux//contexts/default_type - default types for roles .br /etc/selinux//contexts/securetty_types - securetty types for level changes .br /etc/selinux/newrole_pam.conf - optional mapping of commands to separate pam service names .br .SH SEE ALSO .B runcon (1) .SH AUTHORS .nf Anthony Colatrella Tim Fraser Steve Grubb Darrel Goeddel Michael Thompson Dan Walsh policycoreutils-2.3/newrole/newrole.c000066400000000000000000001041141233221606300201000ustar00rootroot00000000000000/************************************************************************ * * newrole * * SYNOPSIS: * * This program allows a user to change their SELinux RBAC role and/or * SELinux TE type (domain) in a manner similar to the way the traditional * UNIX su program allows a user to change their identity. * * USAGE: * * newrole [ -r role ] [ -t type ] [ -l level ] [ -V ] [ -- args ] * * BUILD OPTIONS: * * option USE_PAM: * * Set the USE_PAM constant if you want to authenticate users via PAM. * If USE_PAM is not set, users will be authenticated via direct * access to the shadow password file. * * If you decide to use PAM must be told how to handle newrole. A * good rule-of-thumb might be to tell PAM to handle newrole in the * same way it handles su, except that you should remove the pam_rootok.so * entry so that even root must re-authenticate to change roles. * * If you choose not to use PAM, make sure you have a shadow passwd file * in /etc/shadow. You can use a symlink if your shadow passwd file * lives in another directory. Example: * su * cd /etc * ln -s /etc/auth/shadow shadow * * If you decide not to use PAM, you will also have to make newrole * setuid root, so that it can read the shadow passwd file. * * * Authors: * Anthony Colatrella * Tim Fraser * Steve Grubb * Darrel Goeddel * Michael Thompson * Dan Walsh * *************************************************************************/ #define _GNU_SOURCE #if defined(AUDIT_LOG_PRIV) && !defined(USE_AUDIT) #error AUDIT_LOG_PRIV needs the USE_AUDIT option #endif #if defined(NAMESPACE_PRIV) && !defined(USE_PAM) #error NAMESPACE_PRIV needs the USE_PAM option #endif #include #include /* for malloc(), realloc(), free() */ #include /* for getpwuid() */ #include #include /* to make getuid() and getpwuid() happy */ #include /* for wait() */ #include /* for getopt_long() form of getopt() */ #include #include #include #include /* for is_selinux_enabled() */ #include /* for SECCLASS_CHR_FILE */ #include /* for context-mangling functions */ #include #include /* for SELINUX_DEFAULTUSER */ #include #include /* for getuid(), exit(), getopt() */ #ifdef USE_AUDIT #include #endif #if defined(AUDIT_LOG_PRIV) || (NAMESPACE_PRIV) #include #include #endif #ifdef USE_NLS #include /* for setlocale() */ #include /* for gettext() */ #define _(msgid) gettext (msgid) #else #define _(msgid) (msgid) #endif #ifndef PACKAGE #define PACKAGE "policycoreutils" /* the name of this package lang translation */ #endif #define TRUE 1 #define FALSE 0 /* USAGE_STRING describes the command-line args of this program. */ #define USAGE_STRING "USAGE: newrole [ -r role ] [ -t type ] [ -l level ] [ -p ] [ -V ] [ -- args ]" #ifdef USE_PAM #define PAM_SERVICE_CONFIG "/etc/selinux/newrole_pam.conf"; #endif #define DEFAULT_PATH "/usr/bin:/bin" #define DEFAULT_CONTEXT_SIZE 255 /* first guess at context size */ extern char **environ; /** * Construct from the current range and specified desired level a resulting * range. If the specified level is a range, return that. If it is not, then * construct a range with level as the sensitivity and clearance of the current * context. * * newlevel - the level specified on the command line * range - the range in the current context * * Returns malloc'd memory */ static char *build_new_range(char *newlevel, const char *range) { char *newrangep = NULL; const char *tmpptr; size_t len; /* a missing or empty string */ if (!range || !strlen(range) || !newlevel || !strlen(newlevel)) return NULL; /* if the newlevel is actually a range - just use that */ if (strchr(newlevel, '-')) { newrangep = strdup(newlevel); return newrangep; } /* look for MLS range in current context */ tmpptr = strchr(range, '-'); if (tmpptr) { /* we are inserting into a ranged MLS context */ len = strlen(newlevel) + 1 + strlen(tmpptr + 1) + 1; newrangep = (char *)malloc(len); if (!newrangep) return NULL; snprintf(newrangep, len, "%s-%s", newlevel, tmpptr + 1); } else { /* we are inserting into a currently non-ranged MLS context */ if (!strcmp(newlevel, range)) { newrangep = strdup(range); } else { len = strlen(newlevel) + 1 + strlen(range) + 1; newrangep = (char *)malloc(len); if (!newrangep) return NULL; snprintf(newrangep, len, "%s-%s", newlevel, range); } } return newrangep; } #ifdef USE_PAM /************************************************************************ * * All PAM code goes in this section. * ************************************************************************/ #include /* for PAM functions */ #include /* for misc_conv PAM utility function */ char *service_name = "newrole"; /* authenticate_via_pam() * * in: pw - struct containing data from our user's line in * the passwd file. * out: nothing * return: value condition * ----- --------- * 1 PAM thinks that the user authenticated themselves properly * 0 otherwise * * This function uses PAM to authenticate the user running this * program. This is the only function in this program that makes PAM * calls. */ int authenticate_via_pam(const char *ttyn, pam_handle_t * pam_handle) { int result = 0; /* set to 0 (not authenticated) by default */ int pam_rc; /* pam return code */ const char *tty_name; if (ttyn) { if (strncmp(ttyn, "/dev/", 5) == 0) tty_name = ttyn + 5; else tty_name = ttyn; pam_rc = pam_set_item(pam_handle, PAM_TTY, tty_name); if (pam_rc != PAM_SUCCESS) { fprintf(stderr, _("failed to set PAM_TTY\n")); goto out; } } /* Ask PAM to authenticate the user running this program */ pam_rc = pam_authenticate(pam_handle, 0); if (pam_rc != PAM_SUCCESS) { goto out; } /* Ask PAM to verify acct_mgmt */ pam_rc = pam_acct_mgmt(pam_handle, 0); if (pam_rc == PAM_SUCCESS) { result = 1; /* user authenticated OK! */ } out: return result; } /* authenticate_via_pam() */ #include "hashtab.h" static int free_hashtab_entry(hashtab_key_t key, hashtab_datum_t d, void *args __attribute__ ((unused))) { free(key); free(d); return 0; } static unsigned int reqsymhash(hashtab_t h, hashtab_key_t key) { char *p, *keyp; size_t size; unsigned int val; val = 0; keyp = (char *)key; size = strlen(keyp); for (p = keyp; ((size_t) (p - keyp)) < size; p++) val = (val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p); return val & (h->size - 1); } static int reqsymcmp(hashtab_t h __attribute__ ((unused)), hashtab_key_t key1, hashtab_key_t key2) { char *keyp1, *keyp2; keyp1 = (char *)key1; keyp2 = (char *)key2; return strcmp(keyp1, keyp2); } static hashtab_t app_service_names = NULL; #define PAM_SERVICE_SLOTS 64 static int process_pam_config(FILE * cfg) { const char *config_file_path = PAM_SERVICE_CONFIG; char *line_buf = NULL; unsigned long lineno = 0; size_t len = 0; char *app = NULL; char *service = NULL; int ret; while (getline(&line_buf, &len, cfg) > 0) { char *buffer = line_buf; lineno++; while (isspace(*buffer)) buffer++; if (buffer[0] == '#') continue; if (buffer[0] == '\n' || buffer[0] == '\0') continue; app = service = NULL; ret = sscanf(buffer, "%as %as\n", &app, &service); if (ret < 2 || !app || !service) goto err; ret = hashtab_insert(app_service_names, app, service); if (ret == HASHTAB_OVERFLOW) { fprintf(stderr, _ ("newrole: service name configuration hashtable overflow\n")); goto err; } } free(line_buf); return 0; err: free(app); free(service); fprintf(stderr, _("newrole: %s: error on line %lu.\n"), config_file_path, lineno); free(line_buf); return -1; } /* * Read config file ignoring comment lines. * Files specified one per line executable with a corresponding * pam service name. */ static int read_pam_config() { const char *config_file_path = PAM_SERVICE_CONFIG; FILE *cfg = NULL; cfg = fopen(config_file_path, "r"); if (!cfg) return 0; /* This configuration is optional. */ app_service_names = hashtab_create(reqsymhash, reqsymcmp, PAM_SERVICE_SLOTS); if (!app_service_names) goto err; if (process_pam_config(cfg)) goto err; fclose(cfg); return 0; err: fclose(cfg); return -1; } #else /* else !USE_PAM */ /************************************************************************ * * All shadow passwd code goes in this section. * ************************************************************************/ #include /* for shadow passwd functions */ #include /* for strlen(), memset() */ #define PASSWORD_PROMPT _("Password:") /* prompt for getpass() */ /* authenticate_via_shadow_passwd() * * in: uname - the calling user's user name * out: nothing * return: value condition * ----- --------- * 1 user authenticated themselves properly according to the * shadow passwd file. * 0 otherwise * * This function uses the shadow passwd file to thenticate the user running * this program. */ int authenticate_via_shadow_passwd(const char *uname) { struct spwd *p_shadow_line; char *unencrypted_password_s; char *encrypted_password_s; setspent(); p_shadow_line = getspnam(uname); endspent(); if (!(p_shadow_line)) { fprintf(stderr, _("Cannot find your entry in the shadow " "passwd file.\n")); return 0; } /* Ask user to input unencrypted password */ if (!(unencrypted_password_s = getpass(PASSWORD_PROMPT))) { fprintf(stderr, _("getpass cannot open /dev/tty\n")); return 0; } /* Use crypt() to encrypt user's input password. */ encrypted_password_s = crypt(unencrypted_password_s, p_shadow_line->sp_pwdp); memset(unencrypted_password_s, 0, strlen(unencrypted_password_s)); return (!strcmp(encrypted_password_s, p_shadow_line->sp_pwdp)); } #endif /* if/else USE_PAM */ /** * This function checks to see if the shell is known in /etc/shells. * If so, it returns 1. On error or illegal shell, it returns 0. */ static int verify_shell(const char *shell_name) { int found = 0; const char *buf; if (!(shell_name && shell_name[0])) return found; while ((buf = getusershell()) != NULL) { /* ignore comments */ if (*buf == '#') continue; /* check the shell skipping newline char */ if (!strcmp(shell_name, buf)) { found = 1; break; } } endusershell(); return found; } /** * Determine the Linux user identity to re-authenticate. * If supported and set, use the login uid, as this should be more stable. * Otherwise, use the real uid. * * This function assigns malloc'd memory into the pw_copy struct. * Returns zero on success, non-zero otherwise */ int extract_pw_data(struct passwd *pw_copy) { uid_t uid; struct passwd *pw; #ifdef USE_AUDIT uid = audit_getloginuid(); if (uid == (uid_t) - 1) uid = getuid(); #else uid = getuid(); #endif setpwent(); pw = getpwuid(uid); endpwent(); if (!(pw && pw->pw_name && pw->pw_name[0] && pw->pw_shell && pw->pw_shell[0] && pw->pw_dir && pw->pw_dir[0])) { fprintf(stderr, _("cannot find valid entry in the passwd file.\n")); return -1; } *pw_copy = *pw; pw = pw_copy; pw->pw_name = strdup(pw->pw_name); pw->pw_dir = strdup(pw->pw_dir); pw->pw_shell = strdup(pw->pw_shell); if (!(pw->pw_name && pw->pw_dir && pw->pw_shell)) { fprintf(stderr, _("Out of memory!\n")); goto out_free; } if (verify_shell(pw->pw_shell) == 0) { fprintf(stderr, _("Error! Shell is not valid.\n")); goto out_free; } return 0; out_free: free(pw->pw_name); free(pw->pw_dir); free(pw->pw_shell); return -1; } /** * Either restore the original environment, or set up a minimal one. * * The minimal environment contains: * TERM, DISPLAY and XAUTHORITY - if they are set, preserve values * HOME, SHELL, USER and LOGNAME - set to contents of /etc/passwd * PATH - set to default value DEFAULT_PATH * * Returns zero on success, non-zero otherwise */ static int restore_environment(int preserve_environment, char **old_environ, const struct passwd *pw) { char const *term_env; char const *display_env; char const *xauthority_env; char *term = NULL; /* temporary container */ char *display = NULL; /* temporary container */ char *xauthority = NULL; /* temporary container */ int rc; environ = old_environ; if (preserve_environment) return 0; term_env = getenv("TERM"); display_env = getenv("DISPLAY"); xauthority_env = getenv("XAUTHORITY"); /* Save the variable values we want */ if (term_env) term = strdup(term_env); if (display_env) display = strdup(display_env); if (xauthority_env) xauthority = strdup(xauthority_env); if ((term_env && !term) || (display_env && !display) || (xauthority_env && !xauthority)) { rc = -1; goto out; } /* Construct a new environment */ if ((rc = clearenv())) { fprintf(stderr, _("Unable to clear environment\n")); goto out; } /* Restore that which we saved */ if (term) rc |= setenv("TERM", term, 1); if (display) rc |= setenv("DISPLAY", display, 1); if (xauthority) rc |= setenv("XAUTHORITY", xauthority, 1); rc |= setenv("HOME", pw->pw_dir, 1); rc |= setenv("SHELL", pw->pw_shell, 1); rc |= setenv("USER", pw->pw_name, 1); rc |= setenv("LOGNAME", pw->pw_name, 1); rc |= setenv("PATH", DEFAULT_PATH, 1); out: free(term); free(display); free(xauthority); return rc; } /** * This function will drop the capabilities so that we are left * only with access to the audit system. If the user is root, we leave * the capabilities alone since they already should have access to the * audit netlink socket. * * Returns zero on success, non-zero otherwise */ #if defined(AUDIT_LOG_PRIV) && !defined(NAMESPACE_PRIV) static int drop_capabilities(int full) { uid_t uid = getuid(); if (!uid) return 0; capng_setpid(getpid()); capng_clear(CAPNG_SELECT_BOTH); if (capng_lock() < 0) return -1; /* Change uid */ if (setresuid(uid, uid, uid)) { fprintf(stderr, _("Error changing uid, aborting.\n")); return -1; } if (! full) capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_AUDIT_WRITE); return capng_apply(CAPNG_SELECT_BOTH); } #elif defined(NAMESPACE_PRIV) /** * This function will drop the capabilities so that we are left * only with access to the audit system and the ability to raise * CAP_SYS_ADMIN, CAP_DAC_OVERRIDE, CAP_FOWNER and CAP_CHOWN, * before invoking pam_namespace. These capabilities are needed * for performing bind mounts/unmounts and to create potential new * instance directories with appropriate DAC attributes. If the * user is root, we leave the capabilities alone since they already * should have access to the audit netlink socket and should have * the ability to create/mount/unmount instance directories. * * Returns zero on success, non-zero otherwise */ static int drop_capabilities(int full) { capng_setpid(getpid()); capng_clear(CAPNG_SELECT_BOTH); if (capng_lock() < 0) return -1; uid_t uid = getuid(); /* Change uid */ if (setresuid(uid, uid, uid)) { fprintf(stderr, _("Error changing uid, aborting.\n")); return -1; } if (! full) capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SYS_ADMIN , CAP_FOWNER , CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_SETPCAP, -1); return capng_apply(CAPNG_SELECT_BOTH); } #else static inline int drop_capabilities(__attribute__ ((__unused__)) int full) { return 0; } #endif #ifdef NAMESPACE_PRIV /** * This function will set the uid values to be that of caller's uid, and * will drop any privilages which maybe have been raised. */ static int transition_to_caller_uid() { uid_t uid = getuid(); if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0) { fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n")); return -1; } if (setresuid(uid, uid, uid)) { fprintf(stderr, _("Error changing uid, aborting.\n")); return -1; } return 0; } #endif #ifdef AUDIT_LOG_PRIV /* Send audit message */ static int send_audit_message(int success, security_context_t old_context, security_context_t new_context, const char *ttyn) { char *msg = NULL; int rc; int audit_fd = audit_open(); if (audit_fd < 0) { fprintf(stderr, _("Error connecting to audit system.\n")); return -1; } if (asprintf(&msg, "newrole: old-context=%s new-context=%s", old_context ? old_context : "?", new_context ? new_context : "?") < 0) { fprintf(stderr, _("Error allocating memory.\n")); rc = -1; goto out; } rc = audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, msg, NULL, NULL, ttyn, success); if (rc <= 0) { fprintf(stderr, _("Error sending audit message.\n")); rc = -1; goto out; } rc = 0; out: free(msg); close(audit_fd); return rc; } #else static inline int send_audit_message(int success __attribute__ ((unused)), security_context_t old_context __attribute__ ((unused)), security_context_t new_context __attribute__ ((unused)), const char *ttyn __attribute__ ((unused))) { return 0; } #endif /** * This function attempts to relabel the tty. If this function fails, then * the fd is closed, the contexts are free'd and -1 is returned. On success, * a valid fd is returned and tty_context and new_tty_context are set. * * This function will not fail if it can not relabel the tty when selinux is * in permissive mode. */ static int relabel_tty(const char *ttyn, security_context_t new_context, security_context_t * tty_context, security_context_t * new_tty_context) { int fd; int enforcing = security_getenforce(); security_context_t tty_con = NULL; security_context_t new_tty_con = NULL; if (!ttyn) return 0; if (enforcing < 0) { fprintf(stderr, _("Could not determine enforcing mode.\n")); return -1; } /* Re-open TTY descriptor */ fd = open(ttyn, O_RDWR | O_NONBLOCK); if (fd < 0) { fprintf(stderr, _("Error! Could not open %s.\n"), ttyn); return fd; } fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); if (fgetfilecon(fd, &tty_con) < 0) { fprintf(stderr, _("%s! Could not get current context " "for %s, not relabeling tty.\n"), enforcing ? "Error" : "Warning", ttyn); if (enforcing) goto close_fd; } if (tty_con && (security_compute_relabel(new_context, tty_con, SECCLASS_CHR_FILE, &new_tty_con) < 0)) { fprintf(stderr, _("%s! Could not get new context for %s, " "not relabeling tty.\n"), enforcing ? "Error" : "Warning", ttyn); if (enforcing) goto close_fd; } if (new_tty_con) if (fsetfilecon(fd, new_tty_con) < 0) { fprintf(stderr, _("%s! Could not set new context for %s\n"), enforcing ? "Error" : "Warning", ttyn); freecon(new_tty_con); new_tty_con = NULL; if (enforcing) goto close_fd; } *tty_context = tty_con; *new_tty_context = new_tty_con; return fd; close_fd: freecon(tty_con); close(fd); return -1; } /** * This function attempts to revert the relabeling done to the tty. * fd - referencing the opened ttyn * ttyn - name of tty to restore * tty_context - original context of the tty * new_tty_context - context tty was relabeled to * * Returns zero on success, non-zero otherwise */ static int restore_tty_label(int fd, const char *ttyn, security_context_t tty_context, security_context_t new_tty_context) { int rc = 0; security_context_t chk_tty_context = NULL; if (!ttyn) goto skip_relabel; if (!new_tty_context) goto skip_relabel; /* Verify that the tty still has the context set by newrole. */ if ((rc = fgetfilecon(fd, &chk_tty_context)) < 0) { fprintf(stderr, "Could not fgetfilecon %s.\n", ttyn); goto skip_relabel; } if ((rc = strcmp(chk_tty_context, new_tty_context))) { fprintf(stderr, _("%s changed labels.\n"), ttyn); goto skip_relabel; } if ((rc = fsetfilecon(fd, tty_context)) < 0) fprintf(stderr, _("Warning! Could not restore context for %s\n"), ttyn); skip_relabel: freecon(chk_tty_context); return rc; } /** * Parses and validates the provided command line options and * constructs a new context based on our old context and the * arguments specified on the command line. On success * new_context will be set to valid values, otherwise its value * is left unchanged. * * Returns zero on success, non-zero otherwise. */ static int parse_command_line_arguments(int argc, char **argv, char *ttyn, security_context_t old_context, security_context_t * new_context, int *preserve_environment) { int flag_index; /* flag index in argv[] */ int clflag; /* holds codes for command line flags */ char *role_s = NULL; /* role spec'd by user in argv[] */ char *type_s = NULL; /* type spec'd by user in argv[] */ char *type_ptr = NULL; /* stores malloc'd data from get_default_type */ char *level_s = NULL; /* level spec'd by user in argv[] */ char *range_ptr = NULL; security_context_t new_con = NULL; security_context_t tty_con = NULL; context_t context = NULL; /* manipulatable form of new_context */ const struct option long_options[] = { {"role", 1, 0, 'r'}, {"type", 1, 0, 't'}, {"level", 1, 0, 'l'}, {"preserve-environment", 0, 0, 'p'}, {"version", 0, 0, 'V'}, {NULL, 0, 0, 0} }; *preserve_environment = 0; while (1) { clflag = getopt_long(argc, argv, "r:t:l:pV", long_options, &flag_index); if (clflag == -1) break; switch (clflag) { case 'V': printf("newrole: %s version %s\n", PACKAGE, VERSION); exit(0); break; case 'p': *preserve_environment = 1; break; case 'r': if (role_s) { fprintf(stderr, _("Error: multiple roles specified\n")); return -1; } role_s = optarg; break; case 't': if (type_s) { fprintf(stderr, _("Error: multiple types specified\n")); return -1; } type_s = optarg; break; case 'l': if (!is_selinux_mls_enabled()) { fprintf(stderr, _("Sorry, -l may be used with " "SELinux MLS support.\n")); return -1; } if (level_s) { fprintf(stderr, _("Error: multiple levels " "specified\n")); return -1; } if (ttyn) { if (fgetfilecon(STDIN_FILENO, &tty_con) >= 0) { if (selinux_check_securetty_context (tty_con) < 0) { fprintf(stderr, _ ("Error: you are not allowed to change levels on a non secure terminal \n")); freecon(tty_con); return -1; } freecon(tty_con); } } level_s = optarg; break; default: fprintf(stderr, "%s\n", USAGE_STRING); return -1; } } /* Verify that the combination of command-line arguments are viable */ if (!(role_s || type_s || level_s)) { fprintf(stderr, "%s\n", USAGE_STRING); return -1; } /* Fill in a default type if one hasn't been specified. */ if (role_s && !type_s) { /* get_default_type() returns malloc'd memory */ if (get_default_type(role_s, &type_ptr)) { fprintf(stderr, _("Couldn't get default type.\n")); send_audit_message(0, old_context, new_con, ttyn); return -1; } type_s = type_ptr; } /* Create a temporary new context structure we extract and modify */ context = context_new(old_context); if (!context) { fprintf(stderr, _("failed to get new context.\n")); goto err_free; } /* Modify the temporary new context */ if (role_s) if (context_role_set(context, role_s)) { fprintf(stderr, _("failed to set new role %s\n"), role_s); goto err_free; } if (type_s) if (context_type_set(context, type_s)) { fprintf(stderr, _("failed to set new type %s\n"), type_s); goto err_free; } if (level_s) { range_ptr = build_new_range(level_s, context_range_get(context)); if (!range_ptr) { fprintf(stderr, _("failed to build new range with level %s\n"), level_s); goto err_free; } if (context_range_set(context, range_ptr)) { fprintf(stderr, _("failed to set new range %s\n"), range_ptr); goto err_free; } } /* Construct the final new context */ if (!(new_con = context_str(context))) { fprintf(stderr, _("failed to convert new context to string\n")); goto err_free; } if (security_check_context(new_con) < 0) { fprintf(stderr, _("%s is not a valid context\n"), new_con); send_audit_message(0, old_context, new_con, ttyn); goto err_free; } *new_context = strdup(new_con); if (!*new_context) { fprintf(stderr, _("Unable to allocate memory for new_context")); goto err_free; } free(type_ptr); free(range_ptr); context_free(context); return 0; err_free: free(type_ptr); free(range_ptr); /* Don't free new_con, context_free(context) handles this */ context_free(context); return -1; } /** * Take care of any signal setup */ static int set_signal_handles() { sigset_t empty; /* Empty the signal mask in case someone is blocking a signal */ if (sigemptyset(&empty)) { fprintf(stderr, _("Unable to obtain empty signal set\n")); return -1; } (void)sigprocmask(SIG_SETMASK, &empty, NULL); /* Terminate on SIGHUP. */ if (signal(SIGHUP, SIG_DFL) == SIG_ERR) { fprintf(stderr, _("Unable to set SIGHUP handler\n")); return -1; } return 0; } /************************************************************************ * * All code used for both PAM and shadow passwd goes in this section. * ************************************************************************/ int main(int argc, char *argv[]) { security_context_t new_context = NULL; /* target security context */ security_context_t old_context = NULL; /* original securiy context */ security_context_t tty_context = NULL; /* current context of tty */ security_context_t new_tty_context = NULL; /* new context of tty */ struct passwd pw; /* struct derived from passwd file line */ char *ttyn = NULL; /* tty path */ char **old_environ; int preserve_environment; int fd; pid_t childPid = 0; char *shell_argv0 = NULL; #ifdef USE_PAM int rc; int pam_status; /* pam return code */ pam_handle_t *pam_handle; /* opaque handle used by all PAM functions */ /* This is a jump table of functions for PAM to use when it wants to * * communicate with the user. We'll be using misc_conv(), which is * * provided for us via pam_misc.h. */ struct pam_conv pam_conversation = { misc_conv, NULL }; #endif /* * Step 0: Setup * * Do some intial setup, including dropping capabilities, checking * if it makes sense to continue to run newrole, and setting up * a scrubbed environment. */ if (drop_capabilities(FALSE)) { perror(_("Sorry, newrole failed to drop capabilities\n")); return -1; } if (set_signal_handles()) return -1; #ifdef USE_NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif old_environ = environ; environ = NULL; if (!is_selinux_enabled()) { fprintf(stderr, _("Sorry, newrole may be used only on " "a SELinux kernel.\n")); return -1; } if (security_getenforce() < 0) { fprintf(stderr, _("Could not determine enforcing mode.\n")); return -1; } /* * Step 1: Parse command line and valid arguments * * old_context and ttyn are required for audit logging, * context validation and pam */ if (getprevcon(&old_context)) { fprintf(stderr, _("failed to get old_context.\n")); return -1; } ttyn = ttyname(STDIN_FILENO); if (!ttyn || *ttyn == '\0') { fprintf(stderr, _("Warning! Could not retrieve tty information.\n")); } if (parse_command_line_arguments(argc, argv, ttyn, old_context, &new_context, &preserve_environment)) return -1; /* * Step 2: Authenticate the user. * * Re-authenticate the user running this program. * This is just to help confirm user intent (vs. invocation by * malicious software), not to authorize the operation (which is covered * by policy). Trusted path mechanism would be preferred. */ if (extract_pw_data(&pw)) goto err_free; #ifdef USE_PAM if (read_pam_config()) { fprintf(stderr, _("error on reading PAM service configuration.\n")); goto err_free; } if (app_service_names != NULL && optind < argc) { if (strcmp(argv[optind], "-c") == 0 && optind < (argc - 1)) { /* * Check for a separate pam service name for the * command when invoked by newrole. */ char *cmd = NULL; rc = sscanf(argv[optind + 1], "%as", &cmd); if (rc != EOF && cmd) { char *app_service_name = (char *)hashtab_search(app_service_names, cmd); free(cmd); if (app_service_name != NULL) service_name = app_service_name; } } } pam_status = pam_start(service_name, pw.pw_name, &pam_conversation, &pam_handle); if (pam_status != PAM_SUCCESS) { fprintf(stderr, _("failed to initialize PAM\n")); goto err_free; } if (!authenticate_via_pam(ttyn, pam_handle)) #else if (!authenticate_via_shadow_passwd(pw.pw_name)) #endif { fprintf(stderr, _("newrole: incorrect password for %s\n"), pw.pw_name); send_audit_message(0, old_context, new_context, ttyn); goto err_close_pam; } /* * Step 3: Handle relabeling of the tty. * * Once we authenticate the user, we know that we want to proceed with * the action. Prior to this point, no changes are made the to system. */ fd = relabel_tty(ttyn, new_context, &tty_context, &new_tty_context); if (fd < 0) goto err_close_pam; /* * Step 4: Fork * * Fork, allowing parent to clean up after shell has executed. * Child: reopen stdin, stdout, stderr and exec shell * Parnet: wait for child to die and restore tty's context */ childPid = fork(); if (childPid < 0) { /* fork failed, no child to worry about */ int errsv = errno; fprintf(stderr, _("newrole: failure forking: %s"), strerror(errsv)); if (restore_tty_label(fd, ttyn, tty_context, new_tty_context)) fprintf(stderr, _("Unable to restore tty label...\n")); if (close(fd)) fprintf(stderr, _("Failed to close tty properly\n")); goto err_close_pam; } else if (childPid) { /* PARENT * It doesn't make senes to exit early on errors at this point, * since we are doing cleanup which needs to be done. * We can exit with a bad rc though */ pid_t pid; int exit_code = 0; int status; do { pid = wait(&status); } while (pid < 0 && errno == EINTR); /* Preserve child exit status, unless there is another error. */ if (WIFEXITED(status)) exit_code = WEXITSTATUS(status); if (restore_tty_label(fd, ttyn, tty_context, new_tty_context)) { fprintf(stderr, _("Unable to restore tty label...\n")); exit_code = -1; } freecon(tty_context); freecon(new_tty_context); if (close(fd)) { fprintf(stderr, _("Failed to close tty properly\n")); exit_code = -1; } #ifdef USE_PAM #ifdef NAMESPACE_PRIV pam_status = pam_close_session(pam_handle, 0); if (pam_status != PAM_SUCCESS) { fprintf(stderr, "pam_close_session failed with %s\n", pam_strerror(pam_handle, pam_status)); exit_code = -1; } #endif rc = pam_end(pam_handle, pam_status); if (rc != PAM_SUCCESS) { fprintf(stderr, "pam_end failed with %s\n", pam_strerror(pam_handle, rc)); exit_code = -1; } hashtab_map(app_service_names, free_hashtab_entry, NULL); hashtab_destroy(app_service_names); #endif free(pw.pw_name); free(pw.pw_dir); free(pw.pw_shell); free(shell_argv0); return exit_code; } /* CHILD */ /* Close the tty and reopen descriptors 0 through 2 */ if (ttyn) { if (close(fd) || close(0) || close(1) || close(2)) { fprintf(stderr, _("Could not close descriptors.\n")); goto err_close_pam; } fd = open(ttyn, O_RDWR | O_NONBLOCK); if (fd != 0) goto err_close_pam; fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); fd = open(ttyn, O_RDWR | O_NONBLOCK); if (fd != 1) goto err_close_pam; fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); fd = open(ttyn, O_RDWR | O_NONBLOCK); if (fd != 2) goto err_close_pam; fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); } /* * Step 5: Execute a new shell with the new context in `new_context'. * * Establish context, namesapce and any options for the new shell */ if (optind < 1) optind = 1; /* This is ugly, but use newrole's argv for the exec'd shells argv */ if (asprintf(&shell_argv0, "-%s", pw.pw_shell) < 0) { fprintf(stderr, _("Error allocating shell's argv0.\n")); shell_argv0 = NULL; goto err_close_pam; } argv[optind - 1] = shell_argv0; if (setexeccon(new_context)) { fprintf(stderr, _("Could not set exec context to %s.\n"), new_context); goto err_close_pam; } #ifdef NAMESPACE_PRIV /* Ask PAM to setup session for user running this program */ pam_status = pam_open_session(pam_handle, 0); if (pam_status != PAM_SUCCESS) { fprintf(stderr, "pam_open_session failed with %s\n", pam_strerror(pam_handle, pam_status)); goto err_close_pam; } #endif if (send_audit_message(1, old_context, new_context, ttyn)) goto err_close_pam_session; freecon(old_context); old_context=NULL; freecon(new_context); new_context=NULL; #ifdef NAMESPACE_PRIV if (transition_to_caller_uid()) goto err_close_pam_session; #endif if (drop_capabilities(TRUE)) goto err_close_pam_session; /* Handle environment changes */ if (restore_environment(preserve_environment, old_environ, &pw)) { fprintf(stderr, _("Unable to restore the environment, " "aborting\n")); goto err_close_pam_session; } execv(pw.pw_shell, argv + optind - 1); /* * Error path cleanup * * If we reach here, then we failed to exec the new shell. */ perror(_("failed to exec shell\n")); err_close_pam_session: #ifdef NAMESPACE_PRIV pam_status = pam_close_session(pam_handle, 0); if (pam_status != PAM_SUCCESS) fprintf(stderr, "pam_close_session failed with %s\n", pam_strerror(pam_handle, pam_status)); #endif err_close_pam: #ifdef USE_PAM rc = pam_end(pam_handle, pam_status); if (rc != PAM_SUCCESS) fprintf(stderr, "pam_end failed with %s\n", pam_strerror(pam_handle, rc)); #endif err_free: freecon(tty_context); freecon(new_tty_context); freecon(old_context); freecon(new_context); free(pw.pw_name); free(pw.pw_dir); free(pw.pw_shell); free(shell_argv0); #ifdef USE_PAM if (app_service_names) { hashtab_map(app_service_names, free_hashtab_entry, NULL); hashtab_destroy(app_service_names); } #endif return -1; } /* main() */ policycoreutils-2.3/newrole/newrole.pamd000066400000000000000000000004331233221606300205760ustar00rootroot00000000000000#%PAM-1.0 # Uncomment the next line if you do not want to enter your passwd everytime # auth sufficient pam_rootok.so auth include system-auth account include system-auth password include system-auth session include system-auth session optional pam_xauth.so policycoreutils-2.3/po/000077500000000000000000000000001233221606300152235ustar00rootroot00000000000000policycoreutils-2.3/po/Makefile000066400000000000000000000071641233221606300166730ustar00rootroot00000000000000# # Makefile for the PO files (translation) catalog # TOP = ../.. # What is this package? NLSPACKAGE = policycoreutils POTFILE = $(NLSPACKAGE).pot INSTALL = /usr/bin/install -c -p INSTALL_DATA = $(INSTALL) -m 644 INSTALL_DIR = /usr/bin/install -d # destination directory INSTALL_NLS_DIR = $(DESTDIR)/usr/share/locale # PO catalog handling MSGMERGE = msgmerge MSGMERGE_FLAGS = -q XGETTEXT = xgettext --default-domain=$(NLSPACKAGE) MSGFMT = msgfmt # What do we need to do POFILES = $(wildcard *.po) MOFILES = $(patsubst %.po,%.mo,$(POFILES)) POTFILES = \ ../run_init/open_init_pty.c \ ../run_init/run_init.c \ ../semodule_link/semodule_link.c \ ../audit2allow/audit2allow \ ../semanage/seobject.py \ ../setsebool/setsebool.c \ ../newrole/newrole.c \ ../load_policy/load_policy.c \ ../sestatus/sestatus.c \ ../semodule/semodule.c \ ../setfiles/setfiles.c \ ../semodule_package/semodule_package.c \ ../semodule_deps/semodule_deps.c \ ../semodule_expand/semodule_expand.c \ ../scripts/chcat \ ../scripts/fixfiles \ ../restorecond/stringslist.c \ ../restorecond/restorecond.h \ ../restorecond/utmpwatcher.h \ ../restorecond/stringslist.h \ ../restorecond/restorecond.c \ ../restorecond/utmpwatcher.c \ ../gui/booleansPage.py \ ../gui/fcontextPage.py \ ../gui/loginsPage.py \ ../gui/mappingsPage.py \ ../gui/modulesPage.py \ ../gui/polgen.glade \ ../gui/polgengui.py \ ../gui/portsPage.py \ ../gui/semanagePage.py \ ../gui/statusPage.py \ ../gui/system-config-selinux.glade \ ../gui/system-config-selinux.py \ ../gui/usersPage.py \ ../secon/secon.c \ booleans.py \ ../sepolicy/info.c \ ../sepolicy/search.c \ ../sepolicy/sepolicy.py \ ../sepolicy/sepolicy/communicate.py \ ../sepolicy/sepolicy/__init__.py \ ../sepolicy/sepolicy/network.py \ ../sepolicy/sepolicy/generate.py \ ../sepolicy/sepolicy/sepolicy.glade \ ../sepolicy/sepolicy/gui.py \ ../sepolicy/sepolicy/manpage.py \ ../sepolicy/sepolicy/transition.py \ ../sepolicy/sepolicy/templates/executable.py \ ../sepolicy/sepolicy/templates/__init__.py \ ../sepolicy/sepolicy/templates/network.py \ ../sepolicy/sepolicy/templates/rw.py \ ../sepolicy/sepolicy/templates/script.py \ ../sepolicy/sepolicy/templates/semodule.py \ ../sepolicy/sepolicy/templates/tmp.py \ ../sepolicy/sepolicy/templates/user.py \ ../sepolicy/sepolicy/templates/var_lib.py \ ../sepolicy/sepolicy/templates/var_log.py \ ../sepolicy/sepolicy/templates/var_run.py \ ../sepolicy/sepolicy/templates/var_spool.py #default:: clean all:: $(MOFILES) booleans.py: sepolicy booleans -a > booleans.py $(POTFILE): $(POTFILES) booleans.py $(XGETTEXT) --keyword=_ --keyword=N_ $(POTFILES) @if cmp -s $(NLSPACKAGE).po $(POTFILE); then \ rm -f $(NLSPACKAGE).po; \ else \ mv -f $(NLSPACKAGE).po $(POTFILE); \ fi; \ update-po: Makefile $(POTFILE) refresh-po @rm -f booleans.py refresh-po: Makefile for cat in $(POFILES); do \ lang=`basename $$cat .po`; \ if $(MSGMERGE) $(MSGMERGE_FLAGS) $$lang.po $(POTFILE) > $$lang.pot ; then \ mv -f $$lang.pot $$lang.po ; \ echo "$(MSGMERGE) of $$lang succeeded" ; \ else \ echo "$(MSGMERGE) of $$lang failed" ; \ rm -f $$lang.pot ; \ fi \ done clean: @rm -fv *mo *~ .depend @rm -rf tmp install: $(MOFILES) @for n in $(MOFILES); do \ l=`basename $$n .mo`; \ $(INSTALL_DIR) $(INSTALL_NLS_DIR)/$$l/LC_MESSAGES; \ $(INSTALL_DATA) --verbose $$n $(INSTALL_NLS_DIR)/$$l/LC_MESSAGES/$(NLSPACKAGE).mo; \ done %.mo: %.po $(MSGFMT) -o $@ $< report: @for cat in $(wildcard *.po); do \ echo -n "$$cat: "; \ msgfmt -v --statistics -o /dev/null $$cat; \ done .PHONY: missing depend relabel: policycoreutils-2.3/po/Makefile.in000066400000000000000000000137621233221606300173010ustar00rootroot00000000000000# Makefile for program source directory in GNU NLS utilities package. # Copyright (C) 1995, 1996, 1997 by Ulrich Drepper # # This file file be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU Public License # but which still want to provide support for the GNU gettext functionality. # Please note that the actual code is *not* freely available. PACKAGE = policycoreutils VERSION = 1.1 SHELL = /bin/sh srcdir = . top_srcdir = .. prefix = /usr exec_prefix = ${prefix} datadir = $(prefix)/share localedir = $(datadir)/locale gnulocaledir = $(prefix)/share/locale gettextsrcdir = $(prefix)/share/gettext/po subdir = po INSTALL = /usr/bin/install -c INSTALL_DATA = ${INSTALL} -m 644 MKINSTALLDIRS = mkdir -p CC = gcc GENCAT = GMSGFMT = PATH=../src:$$PATH /usr/bin/msgfmt MSGFMT = /usr/bin/msgfmt XGETTEXT = PATH=../src:$$PATH /usr/bin/xgettext MSGMERGE = PATH=../src:$$PATH msgmerge DEFS = -DHAVE_CONFIG_H CFLAGS = -g -O2 CPPFLAGS = INCLUDES = -I.. -I$(top_srcdir)/intl COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) POFILES = da.po de.po es.po et.po fr.po gl.po id.po it.po ko.po nl.po pl.po pt_BR.po ru.po sv.po GMOFILES = da.gmo de.gmo es.gmo et.gmo fr.gmo gl.gmo id.gmo it.gmo ko.gmo nl.gmo pl.gmo pt_BR.gmo ru.gmo sv.gmo DISTFILES = Makefile.in.in POTFILES.in $(PACKAGE).pot \ $(POFILES) $(GMOFILES) $(SOURCES) POTFILES = \ CATALOGS = #da.gmo de.gmo es.gmo et.gmo fr.gmo gl.gmo id.gmo it.gmo ko.gmo nl.gmo pl.gmo pt_BR.gmo ru.gmo sv.gmo CATOBJEXT = .gmo INSTOBJEXT = .mo .SUFFIXES: .SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat .c.o: $(COMPILE) $< .po.pox: $(MAKE) $(PACKAGE).pot $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox .po.mo: $(MSGFMT) -o $@ $< .po.gmo: file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ && rm -f $$file && $(GMSGFMT) -o $$file $< .po.cat: sed -f ../intl/po2msg.sed < $< > $*.msg \ && rm -f $@ && $(GENCAT) $@ $*.msg all: all-yes all-yes: $(CATALOGS) all-no: $(srcdir)/$(PACKAGE).pot: $(POTFILES) $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \ --add-comments --keyword=_ --keyword=N_ \ --files-from=$(srcdir)/POTFILES.in \ && test ! -f $(PACKAGE).po \ || ( rm -f $(srcdir)/$(PACKAGE).pot \ && mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot ) install: install-exec install-data install-exec: install-data: install-data-yes install-data-no: all install-data-yes: all $(MKINSTALLDIRS) $(DESTDIR)$(datadir); for cat in $(CATALOGS); do \ cat=`basename $$cat`; \ case "$$cat" in \ *.gmo) destdir=$(DESTDIR)$(gnulocaledir);; \ *) destdir=$(DESTDIR)$(localedir);; \ esac; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ dir=$$destdir/$$lang/LC_MESSAGES; \ echo $dir \ $(MKINSTALLDIRS) $$dir; \ if test -r $$cat; then \ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \ else \ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ echo "installing $(srcdir)/$$cat as" \ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \ fi; \ if test -r $$cat.m; then \ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ else \ if test -r $(srcdir)/$$cat.m ; then \ $(INSTALL_DATA) $(srcdir)/$$cat.m \ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ echo "installing $(srcdir)/$$cat as" \ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ else \ true; \ fi; \ fi; \ done if test "$(PACKAGE)" = "gettext"; then \ $(MKINSTALLDIRS) $(DESTDIR)$(gettextsrcdir); \ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \ else \ : ; \ fi # Define this as empty until I found a useful application. installcheck: uninstall: catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ done check: all dvi info tags TAGS ID: mostlyclean: rm -f core core.* *.pox $(PACKAGE).po *.old.po rm -fr *.o clean: mostlyclean rm -f *.gmo distclean: clean rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f $(GMOFILES) distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: update-po $(DISTFILES) dists="$(DISTFILES)"; \ for file in $$dists; do \ ln $(srcdir)/$$file $(distdir) 2> /dev/null \ || cp -p $(srcdir)/$$file $(distdir); \ done update-po: Makefile $(MAKE) $(PACKAGE).pot PATH=`pwd`/../src:$$PATH; \ cd $(srcdir); \ catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ mv $$lang.po $$lang.old.po; \ echo "$$lang:"; \ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \ rm -f $$lang.old.po; \ else \ echo "msgmerge for $$cat failed!"; \ rm -f $$lang.po; \ mv $$lang.old.po $$lang.po; \ fi; \ done POTFILES: POTFILES.in ( if test 'x$(srcdir)' != 'x.'; then \ posrcprefix='$(top_srcdir)/'; \ else \ posrcprefix="../"; \ fi; \ rm -f $@-t $@ \ && (sed -e '/^#/d' -e '/^[ ]*$$/d' \ -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \ | sed -e '$$s/\\$$//') > $@-t \ && chmod a-w $@-t \ && mv $@-t $@ ) Makefile: Makefile.in.in ../config.status POTFILES cd .. \ && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ $(SHELL) ./config.status # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: policycoreutils-2.3/po/Makefile.in.in000066400000000000000000000142571233221606300177060ustar00rootroot00000000000000# Makefile for program source directory in GNU NLS utilities package. # Copyright (C) 1995, 1996, 1997 by Ulrich Drepper # # This file file be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU Public License # but which still want to provide support for the GNU gettext functionality. # Please note that the actual code is *not* freely available. PACKAGE = @PACKAGE@ VERSION = @VERSION@ SHELL = /bin/sh @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ datadir = $(prefix)/@DATADIRNAME@ localedir = $(datadir)/locale gnulocaledir = $(prefix)/share/locale gettextsrcdir = $(prefix)/share/gettext/po subdir = po INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS = @MKINSTALLDIRS@ CC = @CC@ GENCAT = @GENCAT@ GMSGFMT = PATH=../src:$$PATH @GMSGFMT@ MSGFMT = @MSGFMT@ XGETTEXT = PATH=../src:$$PATH @XGETTEXT@ MSGMERGE = PATH=../src:$$PATH msgmerge DEFS = @DEFS@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ INCLUDES = -I.. -I$(top_srcdir)/intl COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) POFILES = @POFILES@ GMOFILES = @GMOFILES@ DISTFILES = Makefile.in.in POTFILES.in $(PACKAGE).pot \ $(POFILES) $(GMOFILES) $(SOURCES) POTFILES = \ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ INSTOBJEXT = @INSTOBJEXT@ .SUFFIXES: .SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat .c.o: $(COMPILE) $< .po.pox: $(MAKE) $(PACKAGE).pot $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox .po.mo: $(MSGFMT) -o $@ $< .po.gmo: file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ && rm -f $$file && $(GMSGFMT) -o $$file $< .po.cat: sed -f ../intl/po2msg.sed < $< > $*.msg \ && rm -f $@ && $(GENCAT) $@ $*.msg all: all-@USE_NLS@ all-yes: $(CATALOGS) all-no: $(srcdir)/$(PACKAGE).pot: $(POTFILES) $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \ --add-comments --keyword=_ --keyword=N_ \ --files-from=$(srcdir)/POTFILES.in \ && test ! -f $(PACKAGE).po \ || ( rm -f $(srcdir)/$(PACKAGE).pot \ && mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot ) install: install-exec install-data install-exec: install-data: install-data-@USE_NLS@ install-data-no: all install-data-yes: all if test -x "$(MKINSTALLDIRS)"; then \ $(MKINSTALLDIRS) $(DESTDIR)$(datadir); \ else \ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir); \ fi @catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ case "$$cat" in \ *.gmo) destdir=$(DESTDIR)$(gnulocaledir);; \ *) destdir=$(DESTDIR)$(localedir);; \ esac; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ dir=$$destdir/$$lang/LC_MESSAGES; \ if test -r "$(MKINSTALLDIRS)"; then \ $(MKINSTALLDIRS) $$dir; \ else \ $(SHELL) $(top_srcdir)/mkinstalldirs $$dir; \ fi; \ if test -r $$cat; then \ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \ else \ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ echo "installing $(srcdir)/$$cat as" \ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \ fi; \ if test -r $$cat.m; then \ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ else \ if test -r $(srcdir)/$$cat.m ; then \ $(INSTALL_DATA) $(srcdir)/$$cat.m \ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ echo "installing $(srcdir)/$$cat as" \ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ else \ true; \ fi; \ fi; \ done if test "$(PACKAGE)" = "gettext"; then \ if test -x "$(MKINSTALLDIRS)"; then \ $(MKINSTALLDIRS) $(DESTDIR)$(gettextsrcdir); \ else \ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(gettextsrcdir); \ fi; \ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \ else \ : ; \ fi # Define this as empty until I found a useful application. installcheck: uninstall: catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ done check: all dvi info tags TAGS ID: mostlyclean: rm -f core core.* *.pox $(PACKAGE).po *.old.po rm -fr *.o clean: mostlyclean rm -f *.gmo distclean: clean rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f $(GMOFILES) distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: update-po $(DISTFILES) dists="$(DISTFILES)"; \ for file in $$dists; do \ ln $(srcdir)/$$file $(distdir) 2> /dev/null \ || cp -p $(srcdir)/$$file $(distdir); \ done update-po: Makefile $(MAKE) $(PACKAGE).pot PATH=`pwd`/../src:$$PATH; \ cd $(srcdir); \ catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ mv $$lang.po $$lang.old.po; \ echo "$$lang:"; \ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \ rm -f $$lang.old.po; \ else \ echo "msgmerge for $$cat failed!"; \ rm -f $$lang.po; \ mv $$lang.old.po $$lang.po; \ fi; \ done POTFILES: POTFILES.in ( if test 'x$(srcdir)' != 'x.'; then \ posrcprefix='$(top_srcdir)/'; \ else \ posrcprefix="../"; \ fi; \ rm -f $@-t $@ \ && (sed -e '/^#/d' -e '/^[ ]*$$/d' \ -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \ | sed -e '$$s/\\$$//') > $@-t \ && chmod a-w $@-t \ && mv $@-t $@ ) Makefile: Makefile.in.in ../config.status POTFILES cd .. \ && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ $(SHELL) ./config.status # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: policycoreutils-2.3/po/POTFILES000066400000000000000000000041671233221606300164030ustar00rootroot00000000000000 ../run_init/open_init_pty.c ../run_init/run_init.c ../semodule_link/semodule_link.c ../audit2allow/audit2allow ../semanage/seobject.py ../setsebool/setsebool.c ../newrole/newrole.c ../load_policy/load_policy.c ../sestatus/sestatus.c ../semodule/semodule.c ../setfiles/setfiles.c ../semodule_package/semodule_package.c ../semodule_deps/semodule_deps.c ../semodule_expand/semodule_expand.c ../scripts/chcat ../scripts/fixfiles ../restorecond/stringslist.c ../restorecond/restorecond.h ../restorecond/utmpwatcher.h ../restorecond/stringslist.h ../restorecond/restorecond.c ../restorecond/utmpwatcher.c ../gui/booleansPage.py ../gui/fcontextPage.py ../gui/loginsPage.py ../gui/mappingsPage.py ../gui/modulesPage.py ../gui/polgen.glade ../gui/polgengui.py ../gui/polgen.py ../gui/portsPage.py ../gui/selinux.tbl ../gui/semanagePage.py ../gui/statusPage.py ../gui/system-config-selinux.glade ../gui/system-config-selinux.py ../gui/usersPage.py ../gui/templates/executable.py ../gui/templates/__init__.py ../gui/templates/network.py ../gui/templates/rw.py ../gui/templates/script.py ../gui/templates/semodule.py ../gui/templates/tmp.py ../gui/templates/user.py ../gui/templates/var_lib.py ../gui/templates/var_log.py ../gui/templates/var_run.py ../gui/templates/var_spool.py ../sepolicy/info.c ../sepolicy/search.c ../sepolicy/sepolicy.py ../sepolicy/sepolicy/communicate.py ../sepolicy/sepolicy/__init__.py ../sepolicy/sepolicy/network.py ../sepolicy/sepolicy/generate.py ../sepolicy/sepolicy/sepolicy.glade ../sepolicy/sepolicy/gui.py ../sepolicy/sepolicy/manpage.py ../sepolicy/sepolicy/transition.py ../sepolicy/sepolicy/templates/executable.py ../sepolicy/sepolicy/templates/__init__.py ../sepolicy/sepolicy/templates/network.py ../sepolicy/sepolicy/templates/rw.py ../sepolicy/sepolicy/templates/script.py ../sepolicy/sepolicy/templates/semodule.py ../sepolicy/sepolicy/templates/tmp.py ../sepolicy/sepolicy/templates/user.py ../sepolicy/sepolicy/templates/var_lib.py ../sepolicy/sepolicy/templates/var_log.py ../sepolicy/sepolicy/templates/var_run.py ../sepolicy/sepolicy/templates/var_spool.py policycoreutils-2.3/po/POTFILES.in000066400000000000000000000030611233221606300170000ustar00rootroot00000000000000run_init/open_init_pty.c run_init/run_init.c semodule_link/semodule_link.c audit2allow/audit2allow semanage/seobject.py setsebool/setsebool.c newrole/newrole.c load_policy/load_policy.c sestatus/sestatus.c semodule/semodule.c setfiles/setfiles.c semodule_package/semodule_package.c semodule_deps/semodule_deps.c semodule_expand/semodule_expand.c scripts/chcat scripts/fixfiles restorecond/stringslist.c restorecond/restorecond.h restorecond/utmpwatcher.h restorecond/stringslist.h restorecond/restorecond.c restorecond/utmpwatcher.c gui/booleansPage.py gui/fcontextPage.py gui/loginsPage.py gui/mappingsPage.py gui/modulesPage.py gui/polgen.glade gui/polgengui.py gui/portsPage.py gui/selinux.tbl gui/semanagePage.py gui/statusPage.py gui/system-config-selinux.glade gui/system-config-selinux.py gui/usersPage.py secon/secon.c sepolicy/info.c sepolicy/search.c sepolicy/sepolicy.py sepolicy/sepolicy/communicate.py sepolicy/sepolicy/__init__.py sepolicy/sepolicy/network.py sepolicy/sepolicy/generate.py sepolicy/sepolicy/sepolicy.glade sepolicy/sepolicy/gui.py sepolicy/sepolicy/manpage.py sepolicy/sepolicy/transition.py sepolicy/sepolicy/templates/executable.py sepolicy/sepolicy/templates/__init__.py sepolicy/sepolicy/templates/network.py sepolicy/sepolicy/templates/rw.py sepolicy/sepolicy/templates/script.py sepolicy/sepolicy/templates/semodule.py sepolicy/sepolicy/templates/tmp.py sepolicy/sepolicy/templates/user.py sepolicy/sepolicy/templates/var_lib.py sepolicy/sepolicy/templates/var_log.py sepolicy/sepolicy/templates/var_run.py sepolicy/sepolicy/templates/var_spool.py policycoreutils-2.3/po/af.po000066400000000000000000003462531233221606300161660ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: msgid "" msgstr "" "Project-Id-Version: Policycoreutils\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-10-10 16:04-0400\n" "PO-Revision-Date: 2012-03-30 18:14+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Afrikaans (http://www.transifex.com/projects/p/fedora/" "language/af/)\n" "Language: af\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../run_init/run_init.c:67 msgid "" "USAGE: run_init