pax_global_header00006660000000000000000000000064123322160630014510gustar00rootroot0000000000000052 comment=1e6482134b9dc2e4480a1cecaf1d366c9d42b0e7 libsemanage-2.3/000077500000000000000000000000001233221606300136235ustar00rootroot00000000000000libsemanage-2.3/.gitignore000066400000000000000000000000621233221606300156110ustar00rootroot00000000000000src/conf-parse.c src/conf-parse.h src/conf-scan.c libsemanage-2.3/COPYING000066400000000000000000000635001233221606300146620ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! libsemanage-2.3/ChangeLog000066400000000000000000000635331233221606300154070ustar00rootroot000000000000002.3 2014-05-06 * Fix memory leak in semanage_genhomedircon from Thomas Hurd. 2.2 2013-10-30 * Avoid duplicate list entries from Dan Walsh. * Add audit support to libsemanage from Dan Walsh. * Remove policy.kern and replace with symlink from Dan Walsh. * Apply a MAX_UID check for genhomedircon from Laurent Bigonville. * Fix man pages from Laurent Bigonville. 2.1.10 2013-02-01 * Add sefcontext_compile to compile regex everytime policy is rebuilt * Cleanup/fix enable/disable/remove module. * redo genhomedircon minuid * fixes from coverity * semanage_store: do not leak memory in semanage_exec_prog * genhomedircon: remove useless conditional in get_home_dirs * genhomedircon: double free in get_home_dirs * fcontext_record: do not leak on error in semanage_fcontext_key_create * genhomedircon: do not leak on failure in write_gen_home_dir_context * semanage_store: do not leak fd * genhomedircon: do not leak shells list * semanage_store: do not leak on strdup failure * semanage_store: rewrite for readability 2.1.9 2012-09-13 * libsemanage: do not set soname needlessly * libsemanage: remove PYTHONLIBDIR and ruby equivalent * do boolean name substitution * Fix segfault for building standard policies. 2.1.8 2012-06-28 * remove build warning when build swig c files * additional makefile support for rubywrap * ignore 80 column limit for readability * semanage_store: fix snprintf length argument by using asprintf * Use default semanage.conf as a fallback * use after free in python bindings 2.1.7 2012-03-28 * Alternate path for semanage.conf * do not link against libpython, this is considered bad in Debian * Allow to build for several ruby version * fallback-user-level 2.1.6 2011-12-21 * add ignoredirs config for genhomedircon * Fallback_user_level can be NULL if you are not using MLS 2.1.5 2011-11-03 * regenerate .pc on VERSION change * maintain mode even if umask is tighter * semanage.conf man page * create man5dir if not exist 2.1.4 2011-09-15 * Create a new preserve_tunables flag * tree: default make target to all not * fix semanage_store_access_check calling arguments 2.1.3 2011-08-26 * python wrapper makefile changes 2.1.2 2011-08-17 * print error debug info for buggy fc * introduce semanage_set_root and friends * throw exceptions in python rather than return * python3 support. * patch for MCS/MLS in user files 2.1.1 2011-08-01 * Remove generated files, expand .gitignore * Use -Werror and change a few prototypes to support it 2.1.0 2011-07-27 * Release, minor version bump 2.0.46 2010-12-16 * Fix compliation under GCC 4.6 by Justin Mattock 2.0.45 2010-03-06 * Add enable/disable patch support from Dan Walsh. * Add usepasswd flag to semanage.conf to disable genhomedircon using passwd from Dan Walsh. * regenerate swig wrappers 2.0.44 2010-02-02 * Replace usage of fmemopen() with sepol_policy_file_set_mem() since glibc < 2.9 does not support binary mode ('b') for fmemopen'd streams. 2.0.43 2009-11-27 * Move libsemanage.so to /usr/lib * Add NAME lines to man pages from Manoj Srivastava 2.0.42 2009-11-18 * Move load_policy from /usr/sbin to /sbin from Dan Walsh. 2.0.41 2009-10-29 * Add pkgconfig file from Eamon Walsh. 2.0.40 2009-10-22 * Add semanage_set_check_contexts() function to disable calling setfiles 2.0.39 2009-09-24 * make swigify 2.0.38 2009-09-16 * Change semodule upgrade behavior to install even if the module is not present from Dan Walsh. * Make genhomedircon trim excess '/' from homedirs from Dan Walsh. 2.0.37 2009-09-04 * Fix persistent dontaudit support to rebuild policy if the dontaudit state is changed from Chad Sellers. 2.0.36 2009-08-24 * Changed bzip-blocksize=0 handling to support existing compressed modules in the store. 2.0.35 2009-08-05 * Revert hard linking of files between tmp/active/previous. 2.0.34 2009-08-05 * Enable configuration of bzip behavior from Stephen Smalley. bzip-blocksize=0 to disable compression and decompression support. bzip-blocksize=1..9 to set the blocksize for compression. bzip-small=true to reduce memory usage for decompression. 2.0.33 2009-07-07 * Maintain disable dontaudit state from Christopher Pardy. 2.0.32 2009-05-28 * Ruby bindings from David Quigley. 2.0.31 2009-01-12 * Policy module compression (bzip) support from Dan Walsh. * Hard link files between tmp/active/previous from Dan Walsh. 2.0.30 2008-11-12 * Add semanage_mls_enabled() interface from Stephen Smalley. 2.0.29 2008-11-11 * Add USER to lines to homedir_template context file from Chris PeBenito. 2.0.28 2008-09-15 * allow fcontext and seuser changes without rebuilding the policy from Dan Walsh 2.0.27 2008-08-05 * Modify genhomedircon to skip %groupname entries. Ultimately we need to expand them to the list of users to support per-role homedir labeling when using the %groupname syntax. 2.0.26 2008-07-29 * Fix bug in genhomedircon fcontext matches logic from Dan Walsh. Strip any trailing slash before appending /*$. 2.0.25 2008-04-21 * Do not call genhomedircon if the policy was not rebuilt from Stephen Smalley. Fixes semanage boolean -D seg fault (bug 441379). 2.0.24 2008-02-26 * make swigify 2.0.23 2008-02-04 * Use vfork rather than fork for libsemanage helpers to reduce memory overhead as suggested by Todd Miller. 2.0.22 2008-02-04 * Free policydb before fork from Joshua Brindle. 2.0.21 2008-02-04 * Drop the base module immediately after expanding to permit memory re-use from Stephen Smalley. 2.0.12 2008-02-02 * Use sepol_set_expand_consume_base to reduce peak memory usage when using semodule from Joshua Brindle. 2.0.19 2008-01-31 * Fix genhomedircon to not override a file context with a homedir context from Todd Miller. 2.0.18 2008-01-28 * Fix spurious out of memory error reports. 2.0.17 2008-01-25 * Merged second version of fix for genhomedircon handling from Caleb Case. 2.0.16 2008-01-24 * Merged fix for genhomedircon handling of missing HOME_DIR or HOME_ROOT templates from Caleb Case. 2.0.15 2007-12-05 * Fix genhomedircon handling of shells and missing user context template from Dan Walsh. * Copy the store path in semanage_select_store from Dan Walsh. 2.0.14 2007-11-05 * Call rmdir() rather than remove() on directory removal so that errno isn't polluted from Stephen Smalley. 2.0.13 2007-11-05 * Allow handle_unknown in base to be overridden by semanage.conf from Stephen Smalley. 2.0.12 2007-10-05 * ustr cleanups from James Antill. * Ensure that /root gets labeled even if using the default context from Dan Walsh. 2.0.11 2007-09-28 * Fix ordering of file_contexts.homedirs from Todd Miller and Dan Walsh. 2.0.10 2007-09-28 * Fix error checking on getpw*_r functions from Todd Miller. * Make genhomedircon skip invalid homedir contexts from Todd Miller. * Set default user and prefix from seusers from Dan Walsh. * Add swigify Makefile target from Dan Walsh. 2.0.9 2007-09-24 * Pass CFLAGS to CC even on link command, per Dennis Gilmore. 2.0.8 2007-09-19 * Clear errno on non-fatal errors to avoid reporting them upon a later error that does not set errno. 2.0.7 2007-09-19 * Improve reporting of system errors, e.g. full filesystem or read-only filesystem from Stephen Smalley. 2.0.6 2007-09-10 * Change to use getpw* function calls to the _r versions from Todd Miller. 2.0.5 2007-08-23 * Replace genhomedircon script with equivalent functionality within libsemanage and introduce disable-genhomedircon option in semanage.conf from Todd Miller. Note: Depends on ustr. 2.0.4 2007-08-16 * Allow dontaudits to be turned off via semanage interface when updating policy from Joshua Brindle. 2.0.3 2007-04-25 * Fix to libsemanage man patches so whatis will work better from Dan Walsh 2.0.2 2007-04-24 * Merged optimizations from Stephen Smalley. - do not set all booleans upon commit, only those whose values have changed - only install the sandbox upon commit if something was rebuilt 2.0.1 2007-03-12 * Merged dbase_file_flush patch from Dan Walsh. This removes any mention of specific tools (e.g. semanage) from the comment header of the auto-generated files, since there are multiple front-end tools. 2.0.0 2007-02-20 * Merged Makefile test target patch from Caleb Case. * Merged get_commit_number function rename patch from Caleb Case. * Merged strnlen -> strlen patch from Todd Miller. 1.10.1 2007-01-26 * Merged python binding fix from Dan Walsh. 1.10.0 2007-01-18 * Updated version for stable branch. 1.9.2 2007-01-08 * Merged patch to optionally reduce disk usage by removing the backup module store and linked policy from Karl MacMillan * Merged patch to correctly propagate return values in libsemanage 1.9.1 2006-11-27 * Merged patch to compile wit -fPIC instead of -fpic from Manoj Srivastava to prevent hitting the global offest table limit. Patch changed to include libselinux and libsemanage in addition to libsepol. 1.8 2006-10-17 * Updated version for release. 1.6.17 2006-09-29 * Merged patch to skip reload if no active store exists and the store path doesn't match the active store path from Dan Walsh. * Merged patch to not destroy sepol handle on error path of connect from James Athey. * Merged patch to add genhomedircon path to semanage.conf from James Athey. 1.6.16 2006-08-14 * Make most copy errors fatal, but allow exceptions for file_contexts.local, seusers, and netfilter_contexts if the source file does not exist in the store. 1.6.15 2006-08-11 * Merged separate local file contexts patch from Chris PeBenito. 1.6.14 2006-08-11 * Merged patch to make most copy errors non-fatal from Dan Walsh. 1.6.13 2006-08-03 * Merged netfilter contexts support from Chris PeBenito. 1.6.12 2006-07-11 * Merged support for read operations on read-only fs from Caleb Case (Tresys Technology). 1.6.11 2006-06-29 * Lindent. 1.6.10 2006-06-26 * Merged setfiles location check patch from Dan Walsh. 1.6.9 2006-06-16 * Merged several fixes from Serge Hallyn: dbase_file_cache: deref of uninit data on error path. dbase_policydb_cache: clear fp to avoid double fclose semanage_fc_sort: destroy temp on error paths 1.6.8 2006-06-02 * Updated default location for setfiles to /sbin to match policycoreutils. This can also be adjusted via semanage.conf using the syntax: [setfiles] path = /path/to/setfiles args = -q -c $@ $< [end] 1.6.7 2006-05-05 * Merged fix warnings patch from Karl MacMillan. 1.6.6 2006-04-14 * Merged updated file context sorting patch from Christopher Ashworth, with bug fix for escaped character flag. 1.6.5 2006-04-13 * Merged file context sorting code from Christopher Ashworth (Tresys Technology), based on fc_sort.c code in refpolicy. 1.6.4 2006-04-12 * Merged python binding t_output_helper removal patch from Dan Walsh. * Regenerated swig files. 1.6.3 2006-03-30 * Merged corrected fix for descriptor leak from Dan Walsh. 1.6.2 2006-03-20 * Merged Makefile PYLIBVER definition patch from Dan Walsh. 1.6.1 2006-03-20 * Merged man page reorganization from Ivan Gyurdiev. 1.6 2006-03-14 * Updated version for release. 1.5.31 2006-03-09 * Merged abort early on merge errors patch from Ivan Gyurdiev. 1.5.30 2006-03-08 * Cleaned up error handling in semanage_split_fc based on a patch by Serge Hallyn (IBM) and suggestions by Ivan Gyurdiev. 1.5.29 2006-02-21 * Merged MLS handling fixes from Ivan Gyurdiev. 1.5.28 2006-02-16 * Merged bug fix for fcontext validate handler from Ivan Gyurdiev. 1.5.27 2006-02-16 * Merged base_merge_components changes from Ivan Gyurdiev. 1.5.26 2006-02-15 * Merged paths array patch from Ivan Gyurdiev. * Merged bug fix patch from Ivan Gyurdiev. 1.5.25 2006-02-14 * Merged improve bindings patch from Ivan Gyurdiev. 1.5.24 2006-02-14 * Merged use PyList patch from Ivan Gyurdiev. * Merged memory leak fix patch from Ivan Gyurdiev. * Merged nodecon support patch from Ivan Gyurdiev. * Merged cleanups patch from Ivan Gyurdiev. * Merged split swig patch from Ivan Gyurdiev. 1.5.23 2006-02-13 * Merged optionals in base patch from Joshua Brindle. 1.5.22 2006-02-13 * Merged treat seusers/users_extra as optional sections patch from Ivan Gyurdiev. * Merged parse_optional fixes from Ivan Gyurdiev. 1.5.21 2006-02-07 * Merged seuser/user_extra support patch from Joshua Brindle. * Merged remote system dbase patch from Ivan Gyurdiev. 1.5.20 2006-02-02 * Merged clone record on set_con patch from Ivan Gyurdiev. 1.5.19 2006-01-30 * Merged fname parameter patch from Ivan Gyurdiev. * Merged more size_t -> unsigned int fixes from Ivan Gyurdiev. * Merged seusers.system patch from Ivan Gyurdiev. * Merged improve port/fcontext API patch from Ivan Gyurdiev. 1.5.18 2006-01-27 * Merged seuser -> seuser_local rename patch from Ivan Gyurdiev. 1.5.17 2006-01-27 * Merged set_create_store, access_check, and is_connected interfaces from Joshua Brindle. 1.5.16 2006-01-19 * Regenerate python wrappers. 1.5.15 2006-01-18 * Merged pywrap Makefile diff from Dan Walsh. * Merged cache management patch from Ivan Gyurdiev. * Merged bugfix for dbase_llist_clear from Ivan Gyurdiev. * Merged remove apply_local function patch from Ivan Gyurdiev. * Merged only do read locking in direct case patch from Ivan Gyurdiev. * Merged cache error path memory leak fix from Ivan Gyurdiev. * Merged auto-generated file header patch from Ivan Gyurdiev. * Merged pywrap test update from Ivan Gyurdiev. * Merged hidden defs update from Ivan Gyurdiev. 1.5.14 2006-01-13 * Merged disallow port overlap patch from Ivan Gyurdiev. 1.5.13 2006-01-12 * Merged join prereq and implementation patches from Ivan Gyurdiev. * Merged join user extra data part 2 patch from Ivan Gyurdiev. * Merged bugfix patch from Ivan Gyurdiev. 1.5.12 2006-01-12 * Merged remove add_local/set_local patch from Ivan Gyurdiev. * Merged user extra data part 1 patch from Ivan Gyurdiev. * Merged size_t -> unsigned int patch from Ivan Gyurdiev. * Merged calloc check in semanage_store patch from Ivan Gyurdiev, bug noticed by Steve Grubb. * Merged cleanups after add/set removal patch from Ivan Gyurdiev. 1.5.11 2006-01-09 * Merged fcontext compare fix from Ivan Gyurdiev. 1.5.10 2006-01-06 * Fixed commit to return the commit number aka policy sequence number. 1.5.9 2006-01-06 * Merged const in APIs patch from Ivan Gyurdiev. * Merged validation of local file contexts patch from Ivan Gyurdiev. * Merged compare2 function patch from Ivan Gyurdiev. * Merged hidden def/proto update patch from Ivan Gyurdiev. 1.5.8 2006-01-05 * Re-applied string and file optimization patch from Russell Coker, with bug fix. 1.5.7 2006-01-05 * Reverted string and file optimization patch from Russell Coker. 1.5.6 2006-01-05 * Clarified error messages from parse_module_headers and parse_base_headers for base/module mismatches. 1.5.5 2006-01-05 * Merged string and file optimization patch from Russell Coker. * Merged swig header reordering patch from Ivan Gyurdiev. * Merged toggle modify on add patch from Ivan Gyurdiev. * Merged ports parser bugfix patch from Ivan Gyurdiev. * Merged fcontext swig patch from Ivan Gyurdiev. * Merged remove add/modify/delete for active booleans patch from Ivan Gyurdiev. * Merged man pages for dbase functions patch from Ivan Gyurdiev. * Merged pywrap tests patch from Ivan Gyurdiev. 1.5.4 2006-01-04 * Merged patch series from Ivan Gyurdiev. This includes patches to: - separate file rw code from linked list - annotate objects - fold together internal headers - support ordering of records in compare function - add active dbase backend, active booleans - return commit numbers for ro database calls - use modified flags to skip rebuild whenever possible - enable port interfaces - update swig interfaces and typemaps - add an API for file_contexts.local and file_contexts - flip the traversal order in iterate/list - reorganize sandbox_expand - add seusers MLS validation - improve dbase spec/documentation - clone record on set/add/modify 1.5.3 2005-12-14 * Merged further header cleanups from Ivan Gyurdiev. 1.5.2 2005-12-13 * Merged toggle modified flag in policydb_modify, fix memory leak in clear_obsolete, polymorphism vs headers fix, and include guards for internal headers patches from Ivan Gyurdiev. 1.5.1 2005-12-12 * Added file-mode= setting to semanage.conf, default to 0644. Changed semanage_copy_file and callers to use this mode when installing policy files to runtime locations. 1.4 2005-12-07 * Updated version for release. 1.3.64 2005-12-06 * Changed semanage_handle_create() to set do_reload based on is_selinux_enabled(). This prevents improper attempts to load policy on a non-SELinux system. 1.3.63 2005-12-05 * Dropped handle from user_del_role interface. 1.3.62 2005-12-05 * Removed defrole interfaces. 1.3.61 2005-11-29 * Merged Makefile python definitions patch from Dan Walsh. 1.3.60 2005-11-29 * Removed is_selinux_mls_enabled() conditionals in seusers and users file parsers. 1.3.59 2005-11-28 * Merged wrap char*** for user_get_roles patch from Joshua Brindle. 1.3.58 2005-11-28 * Merged remove defrole from sepol patch from Ivan Gyurdiev. 1.3.57 2005-11-28 * Merged swig wrappers for modifying users and seusers from Joshua Brindle. 1.3.56 2005-11-16 * Fixed free->key_free bug. 1.3.55 2005-11-16 * Merged clear obsolete patch from Ivan Gyurdiev. 1.3.54 2005-11-15 * Merged modified swigify patch from Dan Walsh (original patch from Joshua Brindle). * Merged move genhomedircon call patch from Chad Sellers. 1.3.53 2005-11-10 * Merged move seuser validation patch from Ivan Gyurdiev. * Merged hidden declaration fixes from Ivan Gyurdiev, with minor corrections. 1.3.52 2005-11-09 * Merged cleanup patch from Ivan Gyurdiev. This renames semanage_module_conn to semanage_direct_handle, and moves sepol handle create/destroy into semanage handle create/destroy to allow use even when disconnected (for the record interfaces). 1.3.51 2005-11-08 * Clear modules modified flag upon disconnect and commit. 1.3.50 2005-11-08 * Added tracking of module modifications and use it to determine whether expand-time checks should be applied on commit. 1.3.49 2005-11-08 * Reverted semanage_set_reload_bools() interface. 1.3.48 2005-11-08 * Disabled calls to port dbase for merge and commit and stubbed out calls to sepol_port interfaces since they are not exported. 1.3.47 2005-11-08 * Merged rename instead of copy patch from Joshua Brindle (Tresys). 1.3.46 2005-11-07 * Added hidden_def/hidden_proto for exported symbols used within libsemanage to eliminate relocations. Wrapped type definitions in exported headers as needed to avoid conflicts. Added src/context_internal.h and src/iface_internal.h. 1.3.45 2005-11-07 * Added semanage_is_managed() interface to allow detection of whether the policy is managed via libsemanage. This enables proper handling in setsebool for non-managed systems. 1.3.44 2005-11-07 * Merged semanage_set_reload_bools() interface from Ivan Gyurdiev, to enable runtime control over preserving active boolean values versus reloading their saved settings upon commit. 1.3.43 2005-11-04 * Merged seuser parser resync, dbase tracking and cleanup, strtol bug, copyright, and assert space patches from Ivan Gyurdiev. 1.3.42 2005-11-04 * Added src/*_internal.h in preparation for other changes. * Added hidden/hidden_proto/hidden_def to src/debug.[hc] and src/seusers.[hc]. 1.3.41 2005-11-03 * Merged interface parse/print, context_to_string interface change, move assert_noeof, and order preserving patches from Ivan Gyurdiev. * Added src/dso.h in preparation for other changes. 1.3.40 2005-11-01 * Merged install seusers, handle/error messages, MLS parsing, and seusers validation patches from Ivan Gyurdiev. 1.3.39 2005-10-31 * Merged record interface, dbase flush, common database code, and record bugfix patches from Ivan Gyurdiev. 1.3.38 2005-10-27 * Merged dbase policydb list and count change from Ivan Gyurdiev. 1.3.37 2005-10-27 * Merged enable dbase and set relay patches from Ivan Gyurdiev. 1.3.36 2005-10-27 * Merged query APIs and dbase_file_set patches from Ivan Gyurdiev. 1.3.35 2005-10-26 * Merged sepol handle passing, seusers support, and policydb cache patches from Ivan Gyurdiev. 1.3.34 2005-10-25 * Merged resync to sepol changes and booleans fixes/improvements patches from Ivan Gyurdiev. 1.3.33 2005-10-25 * Merged support for genhomedircon/homedir template, store selection, explicit policy reload, and semanage.conf relocation from Joshua Brindle. 1.3.32 2005-10-24 * Merged resync to sepol changes and transaction fix patches from Ivan Gyurdiev. 1.3.31 2005-10-21 * Merged reorganize users patch from Ivan Gyurdiev. * Merged remove unused relay functions patch from Ivan Gyurdiev. 1.3.30 2005-10-20 * Fixed policy file leaks in semanage_load_module and semanage_write_module. * Merged further database work from Ivan Gyurdiev. 1.3.29 2005-10-20 * Fixed bug in semanage_direct_disconnect. 1.3.28 2005-10-20 * Merged interface renaming patch from Ivan Gyurdiev. * Merged policy component patch from Ivan Gyurdiev. 1.3.27 2005-10-20 * Renamed 'check=' configuration value to 'expand-check=' for clarity. * Changed semanage_commit_sandbox to check for and report errors on rename(2) calls performed during rollback. 1.3.26 2005-10-19 * Added optional check= configuration value to semanage.conf and updated call to sepol_expand_module to pass its value to control assertion and hierarchy checking on module expansion. 1.3.25 2005-10-19 * Merged fixes for make DESTDIR= builds from Joshua Brindle. 1.3.24 2005-10-19 * Merged default database from Ivan Gyurdiev. * Merged removal of connect requirement in policydb backend from Ivan Gyurdiev. * Merged commit locking fix and lock rename from Joshua Brindle. * Merged transaction rollback in lock patch from Joshua Brindle. 1.3.23 2005-10-18 * Changed default args for load_policy to be null, as it no longer takes a pathname argument and we want to preserve booleans. 1.3.22 2005-10-18 * Merged move local dbase initialization patch from Ivan Gyurdiev. * Merged acquire/release read lock in databases patch from Ivan Gyurdiev. * Merged rename direct -> policydb as appropriate patch from Ivan Gyurdiev. 1.3.21 2005-10-18 * Added calls to sepol_policy_file_set_handle interface prior to invoking sepol operations on policy files. * Updated call to sepol_policydb_from_image to pass the handle. 1.3.20 2005-10-17 * Merged user and port APIs - policy database patch from Ivan Gyurdiev. 1.3.19 2005-10-17 * Converted calls to sepol link_packages and expand_module interfaces from using buffers to using sepol handles for error reporting, and changed direct_connect/disconnect to create/destroy sepol handles. 1.3.18 2005-10-14 * Merged bugfix patch from Ivan Gyurdiev. 1.3.17 2005-10-14 * Merged seuser database patch from Ivan Gyurdiev. Merged direct user/port databases to the handle from Ivan Gyurdiev. 1.3.16 2005-10-14 * Removed obsolete include/semanage/commit_api.h (leftover). Merged seuser record patch from Ivan Gyurdiev. 1.3.15 2005-10-14 * Merged boolean and interface databases from Ivan Gyurdiev. 1.3.14 2005-10-13 * Updated to use get interfaces for hidden sepol_module_package type. 1.3.13 2005-10-13 * Changed semanage_expand_sandbox and semanage_install_active to generate/install the latest policy version supported by libsepol by default (unless overridden by semanage.conf), since libselinux will now downgrade automatically for load_policy. 1.3.12 2005-10-13 * Merged new callback-based error reporting system and ongoing database work from Ivan Gyurdiev. 1.3.11 2005-10-11 * Fixed semanage_install_active() to use the same logic for selecting a policy version as semanage_expand_sandbox(). Dropped dead code from semanage_install_sandbox(). 1.3.10 2005-10-07 * Updated for changes to libsepol, and to only use types and interfaces provided by the shared libsepol. 1.3.9 2005-10-06 * Merged further database work from Ivan Gyurdiev. 1.3.8 2005-10-04 * Merged iterate, redistribute, and dbase split patches from Ivan Gyurdiev. 1.3.7 2005-09-30 * Merged patch series from Ivan Gyurdiev. (pointer typedef elimination, file renames, dbase work, backend separation) 1.3.6 2005-09-28 * Split interfaces from semanage.[hc] into handle.[hc], modules.[hc]. * Separated handle create from connect interface. * Added a constructor for initialization. * Moved up src/include/*.h to src. * Created a symbol map file; dropped dso.h and hidden markings. 1.3.5 2005-09-28 * Merged major update to libsemanage organization and functionality from Karl MacMillan (Tresys). 1.3.4 2005-09-23 * Merged dbase redesign patch from Ivan Gyurdiev. 1.3.3 2005-09-21 * Merged boolean record, stub record handler, and status codes patches from Ivan Gyurdiev. 1.3.2 2005-09-16 * Merged stub iterator functionality from Ivan Gyurdiev. * Merged interface record patch from Ivan Gyurdiev. 1.3.1 2005-09-14 * Merged stub functionality for managing user and port records, and record table code from Ivan Gyurdiev. 1.2 2005-09-06 * Updated version for release. 1.1.6 2005-08-31 * Merged semod.conf template patch from Dan Walsh (Red Hat), but restored location to /usr/share/semod/semod.conf. 1.1.5 2005-08-30 * Fixed several bugs found by valgrind. * Fixed bug in prior patch for the semod_build_module_list leak. 1.1.4 2005-08-25 * Merged errno fix from Joshua Brindle (Tresys). * Merged fix for semod_build_modules_list leak on error path from Serge Hallyn (IBM). Bug found by Coverity. 1.1.3 2005-08-22 * Merged several fixes from Serge Hallyn (IBM). Bugs found by Coverity. * Fixed several other bugs and warnings. 1.1.2 2005-08-02 * Merged patch to move module read/write code from libsemanage to libsepol from Jason Tang (Tresys). 1.1.1 2005-08-02 * Merged relay records patch from Ivan Gyurdiev. * Merged key extract patch from Ivan Gyurdiev. 1.0 2005-07-27 * Initial version. libsemanage-2.3/Makefile000066400000000000000000000007561233221606300152730ustar00rootroot00000000000000all: $(MAKE) -C src all swigify: $(MAKE) -C src swigify pywrap: $(MAKE) -C src pywrap rubywrap: $(MAKE) -C src rubywrap install: $(MAKE) -C include install $(MAKE) -C src install $(MAKE) -C man install install-pywrap: $(MAKE) -C src install-pywrap install-rubywrap: $(MAKE) -C src install-rubywrap relabel: $(MAKE) -C src relabel clean distclean: $(MAKE) -C src $@ $(MAKE) -C tests $@ indent: $(MAKE) -C src $@ $(MAKE) -C include $@ test: all $(MAKE) -C tests test libsemanage-2.3/VERSION000066400000000000000000000000041233221606300146650ustar00rootroot000000000000002.3 libsemanage-2.3/example/000077500000000000000000000000001233221606300152565ustar00rootroot00000000000000libsemanage-2.3/example/test_fcontext.c000066400000000000000000000034751233221606300203240ustar00rootroot00000000000000#include #include #include #include #include #include #include int main(const int argc, const char **argv) { semanage_handle_t *sh = NULL; semanage_fcontext_t *fcontext; semanage_context_t *con; semanage_fcontext_key_t *k; int exist = 0; sh = semanage_handle_create(); if (sh == NULL) { perror("Can't create semanage handle\n"); return -1; } if (semanage_access_check(sh) < 0) { perror("Semanage access check failed\n"); return -1; } if (semanage_connect(sh) < 0) { perror("Semanage connect failed\n"); return -1; } if (semanage_fcontext_key_create(sh, argv[2], SEMANAGE_FCONTEXT_REG, &k) < 0) { fprintf(stderr, "Could not create key for %s", argv[2]); return -1; } if(semanage_fcontext_exists(sh, k, &exist) < 0) { fprintf(stderr,"Could not check if key exists for %s", argv[2]); return -1; } if (exist) { fprintf(stderr,"Could create %s mapping already exists", argv[2]); return -1; } if (semanage_fcontext_create(sh, &fcontext) < 0) { fprintf(stderr,"Could not create file context for %s", argv[2]); return -1; } semanage_fcontext_set_expr(sh, fcontext, argv[2]); if (semanage_context_from_string(sh, argv[1], &con)) { fprintf(stderr,"Could not create context using %s for file context %s", argv[1], argv[2]); return -1; } if (semanage_fcontext_set_con(sh, fcontext, con) < 0) { fprintf(stderr,"Could not set file context for %s", argv[2]); return -1; } semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_REG); if(semanage_fcontext_modify_local(sh, k, fcontext) < 0) { fprintf(stderr,"Could not add file context for %s", argv[2]); return -1; } semanage_fcontext_key_free(k); semanage_fcontext_free(fcontext); return 0; } libsemanage-2.3/include/000077500000000000000000000000001233221606300152465ustar00rootroot00000000000000libsemanage-2.3/include/Makefile000066400000000000000000000004141233221606300167050ustar00rootroot00000000000000# Installation directories. PREFIX ?= $(DESTDIR)/usr INCDIR ?= $(PREFIX)/include/semanage all: install: all test -d $(INCDIR) || install -m 755 -d $(INCDIR) install -m 644 $(wildcard semanage/*.h) $(INCDIR) indent: ../../scripts/Lindent $(wildcard semanage/*.h) libsemanage-2.3/include/semanage/000077500000000000000000000000001233221606300170265ustar00rootroot00000000000000libsemanage-2.3/include/semanage/boolean_record.h000066400000000000000000000031231233221606300221530ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_BOOLEAN_RECORD_H_ #define _SEMANAGE_BOOLEAN_RECORD_H_ #include #ifndef _SEMANAGE_BOOL_DEFINED_ struct semanage_bool; struct semanage_bool_key; typedef struct semanage_bool semanage_bool_t; typedef struct semanage_bool_key semanage_bool_key_t; #define _SEMANAGE_BOOL_DEFINED_ #endif /* Key */ extern int semanage_bool_key_create(semanage_handle_t * handle, const char *name, semanage_bool_key_t ** key); extern int semanage_bool_key_extract(semanage_handle_t * handle, const semanage_bool_t * boolean, semanage_bool_key_t ** key); extern void semanage_bool_key_free(semanage_bool_key_t * key); extern int semanage_bool_compare(const semanage_bool_t * boolean, const semanage_bool_key_t * key); extern int semanage_bool_compare2(const semanage_bool_t * boolean, const semanage_bool_t * boolean2); /* Name */ extern const char *semanage_bool_get_name(const semanage_bool_t * boolean); extern int semanage_bool_set_name(semanage_handle_t * handle, semanage_bool_t * boolean, const char *name); /* Value */ extern int semanage_bool_get_value(const semanage_bool_t * boolean); extern void semanage_bool_set_value(semanage_bool_t * boolean, int value); /* Create/Clone/Destroy */ extern int semanage_bool_create(semanage_handle_t * handle, semanage_bool_t ** bool_ptr); extern int semanage_bool_clone(semanage_handle_t * handle, const semanage_bool_t * boolean, semanage_bool_t ** bool_ptr); extern void semanage_bool_free(semanage_bool_t * boolean); #endif libsemanage-2.3/include/semanage/booleans_active.h000066400000000000000000000020031233221606300223270ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_BOOLEANS_ACTIVE_H_ #define _SEMANAGE_BOOLEANS_ACTIVE_H_ #include #include extern int semanage_bool_set_active(semanage_handle_t * handle, const semanage_bool_key_t * key, const semanage_bool_t * data); extern int semanage_bool_query_active(semanage_handle_t * handle, const semanage_bool_key_t * key, semanage_bool_t ** response); extern int semanage_bool_exists_active(semanage_handle_t * handle, const semanage_bool_key_t * key, int *response); extern int semanage_bool_count_active(semanage_handle_t * handle, unsigned int *response); extern int semanage_bool_iterate_active(semanage_handle_t * handle, int (*handler) (const semanage_bool_t * record, void *varg), void *handler_arg); extern int semanage_bool_list_active(semanage_handle_t * handle, semanage_bool_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/booleans_local.h000066400000000000000000000021661233221606300221600ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_BOOLEANS_LOCAL_H_ #define _SEMANAGE_BOOLEANS_LOCAL_H_ #include #include extern int semanage_bool_modify_local(semanage_handle_t * handle, const semanage_bool_key_t * key, const semanage_bool_t * data); extern int semanage_bool_del_local(semanage_handle_t * handle, const semanage_bool_key_t * key); extern int semanage_bool_query_local(semanage_handle_t * handle, const semanage_bool_key_t * key, semanage_bool_t ** response); extern int semanage_bool_exists_local(semanage_handle_t * handle, const semanage_bool_key_t * key, int *response); extern int semanage_bool_count_local(semanage_handle_t * handle, unsigned int *response); extern int semanage_bool_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_bool_t * record, void *varg), void *handler_arg); extern int semanage_bool_list_local(semanage_handle_t * handle, semanage_bool_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/booleans_policy.h000066400000000000000000000014641233221606300223650ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_BOOLEANS_POLICY_H_ #define _SEMANAGE_BOOLEANS_POLICY_H_ #include #include extern int semanage_bool_query(semanage_handle_t * handle, const semanage_bool_key_t * key, semanage_bool_t ** response); extern int semanage_bool_exists(semanage_handle_t * handle, const semanage_bool_key_t * key, int *response); extern int semanage_bool_count(semanage_handle_t * handle, unsigned int *response); extern int semanage_bool_iterate(semanage_handle_t * handle, int (*handler) (const semanage_bool_t * record, void *varg), void *handler_arg); extern int semanage_bool_list(semanage_handle_t * handle, semanage_bool_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/context_record.h000066400000000000000000000034071233221606300222250ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_CONTEXT_RECORD_H_ #define _SEMANAGE_CONTEXT_RECORD_H_ #include #ifndef _SEMANAGE_CONTEXT_DEFINED_ struct semanage_context; typedef struct semanage_context semanage_context_t; #define _SEMANAGE_CONTEXT_DEFINED_ #endif /* User */ extern const char *semanage_context_get_user(const semanage_context_t * con); extern int semanage_context_set_user(semanage_handle_t * handle, semanage_context_t * con, const char *user); /* Role */ extern const char *semanage_context_get_role(const semanage_context_t * con); extern int semanage_context_set_role(semanage_handle_t * handle, semanage_context_t * con, const char *role); /* Type */ extern const char *semanage_context_get_type(const semanage_context_t * con); extern int semanage_context_set_type(semanage_handle_t * handle, semanage_context_t * con, const char *type); /* MLS */ extern const char *semanage_context_get_mls(const semanage_context_t * con); extern int semanage_context_set_mls(semanage_handle_t * handle, semanage_context_t * con, const char *mls_range); /* Create/Clone/Destroy */ extern int semanage_context_create(semanage_handle_t * handle, semanage_context_t ** con_ptr); extern int semanage_context_clone(semanage_handle_t * handle, const semanage_context_t * con, semanage_context_t ** con_ptr); extern void semanage_context_free(semanage_context_t * con); /* Parse to/from string */ extern int semanage_context_from_string(semanage_handle_t * handle, const char *str, semanage_context_t ** con); extern int semanage_context_to_string(semanage_handle_t * handle, const semanage_context_t * con, char **str_ptr); #endif libsemanage-2.3/include/semanage/debug.h000066400000000000000000000035351233221606300202730ustar00rootroot00000000000000/* Author: Joshua Brindle * Jason Tang * Ivan Gyurdiev * * Copyright (C) 2005 Tresys Technology, LLC * Copyright (C) 2005 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SEMANAGE_DEBUG_H_ #define _SEMANAGE_DEBUG_H_ #include #define SEMANAGE_MSG_ERR 1 #define SEMANAGE_MSG_WARN 2 #define SEMANAGE_MSG_INFO 3 extern int semanage_msg_get_level(semanage_handle_t * handle); extern const char *semanage_msg_get_channel(semanage_handle_t * handle); extern const char *semanage_msg_get_fname(semanage_handle_t * handle); /* Set the messaging callback. * By the default, the callback will print * the message on standard output, in a * particular format. Passing NULL here * indicates that messaging should be suppressed */ extern void semanage_msg_set_callback(semanage_handle_t * handle, #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif void (*msg_callback) (void *varg, semanage_handle_t * handle, const char *fmt, ...), void *msg_callback_arg); #endif libsemanage-2.3/include/semanage/fcontext_record.h000066400000000000000000000046431233221606300223760ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_FCONTEXT_RECORD_H_ #define _SEMANAGE_FCONTEXT_RECORD_H_ #include #include #ifndef _SEMANAGE_FCONTEXT_DEFINED_ struct semanage_fcontext; struct semanage_fcontext_key; typedef struct semanage_fcontext semanage_fcontext_t; typedef struct semanage_fcontext_key semanage_fcontext_key_t; #define _SEMANAGE_FCONTEXT_DEFINED_ #endif /* Key */ extern int semanage_fcontext_compare(const semanage_fcontext_t * fcontext, const semanage_fcontext_key_t * key); extern int semanage_fcontext_compare2(const semanage_fcontext_t * fcontext, const semanage_fcontext_t * fcontext2); extern int semanage_fcontext_key_create(semanage_handle_t * handle, const char *expr, int type, semanage_fcontext_key_t ** key_ptr); extern int semanage_fcontext_key_extract(semanage_handle_t * handle, const semanage_fcontext_t * fcontext, semanage_fcontext_key_t ** key_ptr); extern void semanage_fcontext_key_free(semanage_fcontext_key_t * key); /* Regexp */ extern const char *semanage_fcontext_get_expr(const semanage_fcontext_t * fcontext); extern int semanage_fcontext_set_expr(semanage_handle_t * handle, semanage_fcontext_t * fcontext, const char *expr); /* Type */ #define SEMANAGE_FCONTEXT_ALL 0 #define SEMANAGE_FCONTEXT_REG 1 #define SEMANAGE_FCONTEXT_DIR 2 #define SEMANAGE_FCONTEXT_CHAR 3 #define SEMANAGE_FCONTEXT_BLOCK 4 #define SEMANAGE_FCONTEXT_SOCK 5 #define SEMANAGE_FCONTEXT_LINK 6 #define SEMANAGE_FCONTEXT_PIPE 7 extern int semanage_fcontext_get_type(const semanage_fcontext_t * fcontext); extern const char *semanage_fcontext_get_type_str(int type); extern void semanage_fcontext_set_type(semanage_fcontext_t * fcontext, int type); /* Context */ extern semanage_context_t *semanage_fcontext_get_con(const semanage_fcontext_t * fcontext); extern int semanage_fcontext_set_con(semanage_handle_t * handle, semanage_fcontext_t * fcontext, semanage_context_t * con); /* Create/Clone/Destroy */ extern int semanage_fcontext_create(semanage_handle_t * handle, semanage_fcontext_t ** fcontext_ptr); extern int semanage_fcontext_clone(semanage_handle_t * handle, const semanage_fcontext_t * fcontext, semanage_fcontext_t ** fcontext_ptr); extern void semanage_fcontext_free(semanage_fcontext_t * fcontext); #endif libsemanage-2.3/include/semanage/fcontexts_local.h000066400000000000000000000022371233221606300223720ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_FCONTEXTS_LOCAL_H_ #define _SEMANAGE_FCONTEXTS_LOCAL_H_ #include #include extern int semanage_fcontext_modify_local(semanage_handle_t * handle, const semanage_fcontext_key_t * key, const semanage_fcontext_t * data); extern int semanage_fcontext_del_local(semanage_handle_t * handle, const semanage_fcontext_key_t * key); extern int semanage_fcontext_query_local(semanage_handle_t * handle, const semanage_fcontext_key_t * key, semanage_fcontext_t ** response); extern int semanage_fcontext_exists_local(semanage_handle_t * handle, const semanage_fcontext_key_t * key, int *response); extern int semanage_fcontext_count_local(semanage_handle_t * handle, unsigned int *response); extern int semanage_fcontext_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_fcontext_t * record, void *varg), void *handler_arg); extern int semanage_fcontext_list_local(semanage_handle_t * handle, semanage_fcontext_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/fcontexts_policy.h000066400000000000000000000015611233221606300225760ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_FCONTEXTS_POLICY_H_ #define _SEMANAGE_FCONTEXTS_POLICY_H_ #include #include extern int semanage_fcontext_query(semanage_handle_t * handle, const semanage_fcontext_key_t * key, semanage_fcontext_t ** response); extern int semanage_fcontext_exists(semanage_handle_t * handle, const semanage_fcontext_key_t * key, int *response); extern int semanage_fcontext_count(semanage_handle_t * handle, unsigned int *response); extern int semanage_fcontext_iterate(semanage_handle_t * handle, int (*handler) (const semanage_fcontext_t * record, void *varg), void *handler_arg); extern int semanage_fcontext_list(semanage_handle_t * handle, semanage_fcontext_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/handle.h000066400000000000000000000135501233221606300204360ustar00rootroot00000000000000/* Authors: Joshua Brindle * Jason Tang * * Copyright (C) 2005 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SEMANAGE_HANDLE_H_ #define _SEMANAGE_HANDLE_H_ /* All accesses with semanage are through a "semanage_handle". The * handle may ultimately reference local config files, * the binary policy file, a module store, or a policy management server. */ struct semanage_handle; typedef struct semanage_handle semanage_handle_t; /* Create and return a semanage handle. The handle is initially in the disconnected state. */ semanage_handle_t *semanage_handle_create(void); /* Deallocate all space associated with a semanage_handle_t, including * the pointer itself. CAUTION: this function does not disconnect * from the backend; be sure that a semanage_disconnect() was * previously called if the handle was connected. */ void semanage_handle_destroy(semanage_handle_t *); /* This is the type of connection to the store, for now only * direct is supported */ enum semanage_connect_type { SEMANAGE_CON_INVALID = 0, SEMANAGE_CON_DIRECT, SEMANAGE_CON_POLSERV_LOCAL, SEMANAGE_CON_POLSERV_REMOTE }; /* This function allows you to specify the store to connect to. * It must be called after semanage_handle_create but before * semanage_connect. The argument should be the full path to the store. */ void semanage_select_store(semanage_handle_t * handle, char *path, enum semanage_connect_type storetype); /* Just reload the policy */ int semanage_reload_policy(semanage_handle_t * handle); /* set whether to reload the policy or not after a commit, * 1 for yes (default), 0 for no */ void semanage_set_reload(semanage_handle_t * handle, int do_reload); /* set whether to rebuild the policy on commit, even if no * changes were performed. * 1 for yes, 0 for no (default) */ void semanage_set_rebuild(semanage_handle_t * handle, int do_rebuild); /* create the store if it does not exist, this only has an effect on * direct connections and must be called before semanage_connect * 1 for yes, 0 for no (default) */ void semanage_set_create_store(semanage_handle_t * handle, int create_store); /*Get whether or not dontaudits will be disabled upon commit */ int semanage_get_disable_dontaudit(semanage_handle_t * handle); /* Set whether or not to disable dontaudits upon commit */ void semanage_set_disable_dontaudit(semanage_handle_t * handle, int disable_dontaudit); /* Set whether or not to execute setfiles to check file contexts upon commit */ void semanage_set_check_contexts(semanage_handle_t * sh, int do_check_contexts); /* Check whether policy is managed via libsemanage on this system. * Must be called prior to trying to connect. * Return 1 if policy is managed via libsemanage on this system, * 0 if policy is not managed, or -1 on error. */ int semanage_is_managed(semanage_handle_t *); /* "Connect" to a manager based on the configuration and * associate the provided handle with the connection. * If the connect fails then this function returns a negative value, * else it returns zero. */ int semanage_connect(semanage_handle_t *); /* Disconnect from the manager given by the handle. If already * disconnected then this function does nothing. Return 0 if * disconnected properly or already disconnected, negative value on * error. */ int semanage_disconnect(semanage_handle_t *); /* Attempt to obtain a transaction lock on the manager. If another * process has the lock then this function may block, depending upon * the timeout value in the handle. * * Note that if the semanage_handle has not yet obtained a transaction * lock whenever a writer function is called, there will be an * implicit call to this function. */ int semanage_begin_transaction(semanage_handle_t *); /* Attempt to commit all changes since this transaction began. If the * commit is successful then increment the "policy sequence number" * and then release the transaction lock. Return that policy number * afterwards, or -1 on error. */ int semanage_commit(semanage_handle_t *); #define SEMANAGE_CAN_READ 1 #define SEMANAGE_CAN_WRITE 2 /* returns SEMANAGE_CAN_READ or SEMANAGE_CAN_WRITE if the store is readable * or writable, respectively. <0 if an error occured */ int semanage_access_check(semanage_handle_t * sh); /* returns 0 if not connected, 1 if connected */ int semanage_is_connected(semanage_handle_t * sh); /* returns 1 if policy is MLS, 0 otherwise. */ int semanage_mls_enabled(semanage_handle_t *sh); /* Change to alternate selinux root path */ int semanage_set_root(const char *path); /* Get whether or not needless unused branch of tunables would be preserved */ int semanage_get_preserve_tunables(semanage_handle_t * handle); /* Set whether or not to preserve the needless unused branch of tunables */ void semanage_set_preserve_tunables(semanage_handle_t * handle, int preserve_tunables); /* META NOTES * * For all functions a non-negative number indicates success. For some * functions a >=0 returned value is the "policy sequence number". This * number keeps tracks of policy revisions and is used to detect if * one semanage client has committed policy changes while another is * still connected. */ #endif libsemanage-2.3/include/semanage/iface_record.h000066400000000000000000000037131233221606300216100ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_IFACE_RECORD_H_ #define _SEMANAGE_IFACE_RECORD_H_ #include #include #ifndef _SEMANAGE_IFACE_DEFINED_ struct semanage_iface; struct semanage_iface_key; typedef struct semanage_iface semanage_iface_t; typedef struct semanage_iface_key semanage_iface_key_t; #define _SEMANAGE_IFACE_DEFINED_ #endif /* Key */ extern int semanage_iface_compare(const semanage_iface_t * iface, const semanage_iface_key_t * key); extern int semanage_iface_compare2(const semanage_iface_t * iface, const semanage_iface_t * iface2); extern int semanage_iface_key_create(semanage_handle_t * handle, const char *name, semanage_iface_key_t ** key_ptr); extern int semanage_iface_key_extract(semanage_handle_t * handle, const semanage_iface_t * iface, semanage_iface_key_t ** key_ptr); extern void semanage_iface_key_free(semanage_iface_key_t * key); /* Name */ extern const char *semanage_iface_get_name(const semanage_iface_t * iface); extern int semanage_iface_set_name(semanage_handle_t * handle, semanage_iface_t * iface, const char *name); /* Context */ extern semanage_context_t *semanage_iface_get_ifcon(const semanage_iface_t * iface); extern int semanage_iface_set_ifcon(semanage_handle_t * handle, semanage_iface_t * iface, semanage_context_t * con); extern semanage_context_t *semanage_iface_get_msgcon(const semanage_iface_t * iface); extern int semanage_iface_set_msgcon(semanage_handle_t * handle, semanage_iface_t * iface, semanage_context_t * con); /* Create/Clone/Destroy */ extern int semanage_iface_create(semanage_handle_t * handle, semanage_iface_t ** iface_ptr); extern int semanage_iface_clone(semanage_handle_t * handle, const semanage_iface_t * iface, semanage_iface_t ** iface_ptr); extern void semanage_iface_free(semanage_iface_t * iface); #endif libsemanage-2.3/include/semanage/interfaces_local.h000066400000000000000000000021771233221606300225030ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_INTERFACES_LOCAL_H_ #define _SEMANAGE_INTERFACES_LOCAL_H_ #include #include extern int semanage_iface_modify_local(semanage_handle_t * handle, const semanage_iface_key_t * key, const semanage_iface_t * data); extern int semanage_iface_del_local(semanage_handle_t * handle, const semanage_iface_key_t * key); extern int semanage_iface_query_local(semanage_handle_t * handle, const semanage_iface_key_t * key, semanage_iface_t ** response); extern int semanage_iface_exists_local(semanage_handle_t * handle, const semanage_iface_key_t * key, int *response); extern int semanage_iface_count_local(semanage_handle_t * handle, unsigned int *response); extern int semanage_iface_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_iface_t * record, void *varg), void *handler_arg); extern int semanage_iface_list_local(semanage_handle_t * handle, semanage_iface_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/interfaces_policy.h000066400000000000000000000015021233221606300226770ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_INTERFACES_POLICY_H_ #define _SEMANAGE_INTERFACES_POLICY_H_ #include #include extern int semanage_iface_query(semanage_handle_t * handle, const semanage_iface_key_t * key, semanage_iface_t ** response); extern int semanage_iface_exists(semanage_handle_t * handle, const semanage_iface_key_t * key, int *response); extern int semanage_iface_count(semanage_handle_t * handle, unsigned int *response); extern int semanage_iface_iterate(semanage_handle_t * handle, int (*handler) (const semanage_iface_t * record, void *varg), void *handler_arg); extern int semanage_iface_list(semanage_handle_t * handle, semanage_iface_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/modules.h000066400000000000000000000047101233221606300206510ustar00rootroot00000000000000/* Authors: Joshua Brindle * Jason Tang * * Copyright (C) 2005 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SEMANAGE_MODULES_H_ #define _SEMANAGE_MODULES_H_ #include #include /* High level module management functions. These are all part of * a transaction */ int semanage_module_install(semanage_handle_t *, char *module_data, size_t data_len); int semanage_module_install_file(semanage_handle_t *, const char *module_name); int semanage_module_upgrade(semanage_handle_t *, char *module_data, size_t data_len); int semanage_module_upgrade_file(semanage_handle_t *, const char *module_name); int semanage_module_install_base(semanage_handle_t *, char *module_data, size_t data_len); int semanage_module_install_base_file(semanage_handle_t *, const char *module_name); int semanage_module_enable(semanage_handle_t *, char *module_name); int semanage_module_disable(semanage_handle_t *, char *module_name); int semanage_module_remove(semanage_handle_t *, char *module_name); /* semanage_module_info is for getting information on installed modules, only name and version, and enabled/disabled flag at this time */ typedef struct semanage_module_info semanage_module_info_t; int semanage_module_list(semanage_handle_t *, semanage_module_info_t **, int *num_modules); void semanage_module_info_datum_destroy(semanage_module_info_t *); semanage_module_info_t *semanage_module_list_nth(semanage_module_info_t * list, int n); const char *semanage_module_get_name(semanage_module_info_t *); const char *semanage_module_get_version(semanage_module_info_t *); int semanage_module_get_enabled(semanage_module_info_t *); #endif libsemanage-2.3/include/semanage/node_record.h000066400000000000000000000055221233221606300214660ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_NODE_RECORD_H_ #define _SEMANAGE_NODE_RECORD_H_ #include #include #include #ifndef _SEMANAGE_NODE_DEFINED_ struct semanage_node; struct semanage_node_key; typedef struct semanage_node semanage_node_t; typedef struct semanage_node_key semanage_node_key_t; #define _SEMANAGE_NODE_DEFINED_ #endif #define SEMANAGE_PROTO_IP4 0 #define SEMANAGE_PROTO_IP6 1 /* Key */ extern int semanage_node_compare(const semanage_node_t * node, const semanage_node_key_t * key); extern int semanage_node_compare2(const semanage_node_t * node, const semanage_node_t * node2); extern int semanage_node_key_create(semanage_handle_t * handle, const char *addr, const char *mask, int proto, semanage_node_key_t ** key_ptr); extern int semanage_node_key_extract(semanage_handle_t * handle, const semanage_node_t * node, semanage_node_key_t ** key_ptr); extern void semanage_node_key_free(semanage_node_key_t * key); /* Address */ extern int semanage_node_get_addr(semanage_handle_t * handle, const semanage_node_t * node, char **addr); extern int semanage_node_get_addr_bytes(semanage_handle_t * handle, const semanage_node_t * node, char **addr, size_t * addr_sz); extern int semanage_node_set_addr(semanage_handle_t * handle, semanage_node_t * node, int proto, const char *addr); extern int semanage_node_set_addr_bytes(semanage_handle_t * handle, semanage_node_t * node, const char *addr, size_t addr_sz); /* Netmask */ extern int semanage_node_get_mask(semanage_handle_t * handle, const semanage_node_t * node, char **mask); extern int semanage_node_get_mask_bytes(semanage_handle_t * handle, const semanage_node_t * node, char **mask, size_t * mask_sz); extern int semanage_node_set_mask(semanage_handle_t * handle, semanage_node_t * node, int proto, const char *mask); extern int semanage_node_set_mask_bytes(semanage_handle_t * handle, semanage_node_t * node, const char *mask, size_t mask_sz); /* Protocol */ extern int semanage_node_get_proto(const semanage_node_t * node); extern void semanage_node_set_proto(semanage_node_t * node, int proto); extern const char *semanage_node_get_proto_str(int proto); /* Context */ extern semanage_context_t *semanage_node_get_con(const semanage_node_t * node); extern int semanage_node_set_con(semanage_handle_t * handle, semanage_node_t * node, semanage_context_t * con); /* Create/Clone/Destroy */ extern int semanage_node_create(semanage_handle_t * handle, semanage_node_t ** node_ptr); extern int semanage_node_clone(semanage_handle_t * handle, const semanage_node_t * node, semanage_node_t ** node_ptr); extern void semanage_node_free(semanage_node_t * node); #endif libsemanage-2.3/include/semanage/nodes_local.h000066400000000000000000000021551233221606300214640ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_NODES_LOCAL_H_ #define _SEMANAGE_NODES_LOCAL_H_ #include #include extern int semanage_node_modify_local(semanage_handle_t * handle, const semanage_node_key_t * key, const semanage_node_t * data); extern int semanage_node_del_local(semanage_handle_t * handle, const semanage_node_key_t * key); extern int semanage_node_query_local(semanage_handle_t * handle, const semanage_node_key_t * key, semanage_node_t ** response); extern int semanage_node_exists_local(semanage_handle_t * handle, const semanage_node_key_t * key, int *response); extern int semanage_node_count_local(semanage_handle_t * handle, unsigned int *response); extern int semanage_node_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_node_t * record, void *varg), void *handler_arg); extern int semanage_node_list_local(semanage_handle_t * handle, semanage_node_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/nodes_policy.h000066400000000000000000000014531233221606300216710ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_NODES_POLICY_H_ #define _SEMANAGE_NODES_POLICY_H_ #include #include extern int semanage_node_query(semanage_handle_t * handle, const semanage_node_key_t * key, semanage_node_t ** response); extern int semanage_node_exists(semanage_handle_t * handle, const semanage_node_key_t * key, int *response); extern int semanage_node_count(semanage_handle_t * handle, unsigned int *response); extern int semanage_node_iterate(semanage_handle_t * handle, int (*handler) (const semanage_node_t * record, void *varg), void *handler_arg); extern int semanage_node_list(semanage_handle_t * handle, semanage_node_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/port_record.h000066400000000000000000000040411233221606300215200ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_PORT_RECORD_H_ #define _SEMANAGE_PORT_RECORD_H_ #include #include #ifndef _SEMANAGE_PORT_DEFINED_ struct semanage_port; struct semanage_port_key; typedef struct semanage_port semanage_port_t; typedef struct semanage_port_key semanage_port_key_t; #define _SEMANAGE_PORT_DEFINED_ #endif #define SEMANAGE_PROTO_UDP 0 #define SEMANAGE_PROTO_TCP 1 /* Key */ extern int semanage_port_compare(const semanage_port_t * port, const semanage_port_key_t * key); extern int semanage_port_compare2(const semanage_port_t * port, const semanage_port_t * port2); extern int semanage_port_key_create(semanage_handle_t * handle, int low, int high, int proto, semanage_port_key_t ** key_ptr); extern int semanage_port_key_extract(semanage_handle_t * handle, const semanage_port_t * port, semanage_port_key_t ** key_ptr); extern void semanage_port_key_free(semanage_port_key_t * key); /* Protocol */ extern int semanage_port_get_proto(const semanage_port_t * port); extern void semanage_port_set_proto(semanage_port_t * port, int proto); extern const char *semanage_port_get_proto_str(int proto); /* Port */ extern int semanage_port_get_low(const semanage_port_t * port); extern int semanage_port_get_high(const semanage_port_t * port); extern void semanage_port_set_port(semanage_port_t * port, int port_num); extern void semanage_port_set_range(semanage_port_t * port, int low, int high); /* Context */ extern semanage_context_t *semanage_port_get_con(const semanage_port_t * port); extern int semanage_port_set_con(semanage_handle_t * handle, semanage_port_t * port, semanage_context_t * con); /* Create/Clone/Destroy */ extern int semanage_port_create(semanage_handle_t * handle, semanage_port_t ** port_ptr); extern int semanage_port_clone(semanage_handle_t * handle, const semanage_port_t * port, semanage_port_t ** port_ptr); extern void semanage_port_free(semanage_port_t * port); #endif libsemanage-2.3/include/semanage/ports_local.h000066400000000000000000000021551233221606300215230ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_PORTS_LOCAL_H_ #define _SEMANAGE_PORTS_LOCAL_H_ #include #include extern int semanage_port_modify_local(semanage_handle_t * handle, const semanage_port_key_t * key, const semanage_port_t * data); extern int semanage_port_del_local(semanage_handle_t * handle, const semanage_port_key_t * key); extern int semanage_port_query_local(semanage_handle_t * handle, const semanage_port_key_t * key, semanage_port_t ** response); extern int semanage_port_exists_local(semanage_handle_t * handle, const semanage_port_key_t * key, int *response); extern int semanage_port_count_local(semanage_handle_t * handle, unsigned int *response); extern int semanage_port_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_port_t * record, void *varg), void *handler_arg); extern int semanage_port_list_local(semanage_handle_t * handle, semanage_port_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/ports_policy.h000066400000000000000000000014531233221606300217300ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_PORTS_POLICY_H_ #define _SEMANAGE_PORTS_POLICY_H_ #include #include extern int semanage_port_query(semanage_handle_t * handle, const semanage_port_key_t * key, semanage_port_t ** response); extern int semanage_port_exists(semanage_handle_t * handle, const semanage_port_key_t * key, int *response); extern int semanage_port_count(semanage_handle_t * handle, unsigned int *response); extern int semanage_port_iterate(semanage_handle_t * handle, int (*handler) (const semanage_port_t * record, void *varg), void *handler_arg); extern int semanage_port_list(semanage_handle_t * handle, semanage_port_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/semanage.h000066400000000000000000000035701233221606300207640ustar00rootroot00000000000000/* Authors: Joshua Brindle * Jason Tang * * Copyright (C) 2005 Tresys Technology, LLC * Copyright (C) 2005 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SEMANAGE_SEMANAGE_H_ #define _SEMANAGE_SEMANAGE_H_ #include #include #include /* Records */ #include #include #include #include #include #include #include /* Dbase */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif libsemanage-2.3/include/semanage/seuser_record.h000066400000000000000000000036051233221606300220470ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_SEUSER_RECORD_H_ #define _SEMANAGE_SEUSER_RECORD_H_ #include struct semanage_seuser; struct semanage_seuser_key; typedef struct semanage_seuser semanage_seuser_t; typedef struct semanage_seuser_key semanage_seuser_key_t; /* Key */ extern int semanage_seuser_key_create(semanage_handle_t * handle, const char *name, semanage_seuser_key_t ** key); extern int semanage_seuser_key_extract(semanage_handle_t * handle, const semanage_seuser_t * seuser, semanage_seuser_key_t ** key); extern void semanage_seuser_key_free(semanage_seuser_key_t * key); extern int semanage_seuser_compare(const semanage_seuser_t * seuser, const semanage_seuser_key_t * key); extern int semanage_seuser_compare2(const semanage_seuser_t * seuser, const semanage_seuser_t * seuser2); /* Name */ extern const char *semanage_seuser_get_name(const semanage_seuser_t * seuser); extern int semanage_seuser_set_name(semanage_handle_t * handle, semanage_seuser_t * seuser, const char *name); /* Selinux Name */ extern const char *semanage_seuser_get_sename(const semanage_seuser_t * seuser); extern int semanage_seuser_set_sename(semanage_handle_t * handle, semanage_seuser_t * seuser, const char *sename); /* MLS */ extern const char *semanage_seuser_get_mlsrange(const semanage_seuser_t * seuser); extern int semanage_seuser_set_mlsrange(semanage_handle_t * handle, semanage_seuser_t * seuser, const char *mls_range); /* Create/Clone/Destroy */ extern int semanage_seuser_create(semanage_handle_t * handle, semanage_seuser_t ** seuser_ptr); extern int semanage_seuser_clone(semanage_handle_t * handle, const semanage_seuser_t * seuser, semanage_seuser_t ** seuser_ptr); extern void semanage_seuser_free(semanage_seuser_t * seuser); #endif libsemanage-2.3/include/semanage/seusers_local.h000066400000000000000000000021721233221606300220440ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_SEUSERS_LOCAL_H_ #define _SEMANAGE_SEUSERS_LOCAL_H_ #include #include extern int semanage_seuser_modify_local(semanage_handle_t * handle, const semanage_seuser_key_t * key, const semanage_seuser_t * data); extern int semanage_seuser_del_local(semanage_handle_t * handle, const semanage_seuser_key_t * key); extern int semanage_seuser_query_local(semanage_handle_t * handle, const semanage_seuser_key_t * key, semanage_seuser_t ** response); extern int semanage_seuser_exists_local(semanage_handle_t * handle, const semanage_seuser_key_t * key, int *response); extern int semanage_seuser_count_local(semanage_handle_t * handle, unsigned int *response); extern int semanage_seuser_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_seuser_t * record, void *varg), void *handler_arg); extern int semanage_seuser_list_local(semanage_handle_t * handle, semanage_seuser_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/seusers_policy.h000066400000000000000000000015031233221606300222460ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_SEUSERS_POLICY_H_ #define _SEMANAGE_SEUSERS_POLICY_H_ #include #include extern int semanage_seuser_query(semanage_handle_t * handle, const semanage_seuser_key_t * key, semanage_seuser_t ** response); extern int semanage_seuser_exists(semanage_handle_t * handle, const semanage_seuser_key_t * key, int *response); extern int semanage_seuser_count(semanage_handle_t * handle, unsigned int *response); extern int semanage_seuser_iterate(semanage_handle_t * handle, int (*handler) (const semanage_seuser_t * record, void *varg), void *handler_arg); extern int semanage_seuser_list(semanage_handle_t * handle, semanage_seuser_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/user_record.h000066400000000000000000000053671233221606300215260ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_USER_RECORD_H_ #define _SEMANAGE_USER_RECORD_H_ #include #include struct semanage_user; typedef struct semanage_user semanage_user_t; #ifndef _SEMANAGE_USER_KEY_DEFINED_ struct semanage_user_key; typedef struct semanage_user_key semanage_user_key_t; #define _SEMANAGE_USER_KEY_DEFINED_ #endif /* Key */ extern int semanage_user_key_create(semanage_handle_t * handle, const char *name, semanage_user_key_t ** key); extern int semanage_user_key_extract(semanage_handle_t * handle, const semanage_user_t * user, semanage_user_key_t ** key); extern void semanage_user_key_free(semanage_user_key_t * key); extern int semanage_user_compare(const semanage_user_t * user, const semanage_user_key_t * key); extern int semanage_user_compare2(const semanage_user_t * user, const semanage_user_t * user2); /* Name */ extern const char *semanage_user_get_name(const semanage_user_t * user); extern int semanage_user_set_name(semanage_handle_t * handle, semanage_user_t * user, const char *name); /* Labeling prefix */ extern const char *semanage_user_get_prefix(const semanage_user_t * user); extern int semanage_user_set_prefix(semanage_handle_t * handle, semanage_user_t * user, const char *name); /* MLS */ extern const char *semanage_user_get_mlslevel(const semanage_user_t * user); extern int semanage_user_set_mlslevel(semanage_handle_t * handle, semanage_user_t * user, const char *mls_level); extern const char *semanage_user_get_mlsrange(const semanage_user_t * user); extern int semanage_user_set_mlsrange(semanage_handle_t * handle, semanage_user_t * user, const char *mls_range); /* Role management */ extern int semanage_user_get_num_roles(const semanage_user_t * user); extern int semanage_user_add_role(semanage_handle_t * handle, semanage_user_t * user, const char *role); extern void semanage_user_del_role(semanage_user_t * user, const char *role); extern int semanage_user_has_role(const semanage_user_t * user, const char *role); extern int semanage_user_get_roles(semanage_handle_t * handle, const semanage_user_t * user, const char ***roles_arr, unsigned int *num_roles); extern int semanage_user_set_roles(semanage_handle_t * handle, semanage_user_t * user, const char **roles_arr, unsigned int num_roles); /* Create/Clone/Destroy */ extern int semanage_user_create(semanage_handle_t * handle, semanage_user_t ** user_ptr); extern int semanage_user_clone(semanage_handle_t * handle, const semanage_user_t * user, semanage_user_t ** user_ptr); extern void semanage_user_free(semanage_user_t * user); #endif libsemanage-2.3/include/semanage/users_local.h000066400000000000000000000021551233221606300215150ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_USERS_LOCAL_H_ #define _SEMANAGE_USERS_LOCAL_H_ #include #include extern int semanage_user_modify_local(semanage_handle_t * handle, const semanage_user_key_t * key, const semanage_user_t * data); extern int semanage_user_del_local(semanage_handle_t * handle, const semanage_user_key_t * key); extern int semanage_user_query_local(semanage_handle_t * handle, const semanage_user_key_t * key, semanage_user_t ** response); extern int semanage_user_exists_local(semanage_handle_t * handle, const semanage_user_key_t * key, int *response); extern int semanage_user_count_local(semanage_handle_t * handle, unsigned int *response); extern int semanage_user_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_user_t * record, void *varg), void *handler_arg); extern int semanage_user_list_local(semanage_handle_t * handle, semanage_user_t *** records, unsigned int *count); #endif libsemanage-2.3/include/semanage/users_policy.h000066400000000000000000000014531233221606300217220ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_USERS_POLICY_H_ #define _SEMANAGE_USERS_POLICY_H_ #include #include extern int semanage_user_query(semanage_handle_t * handle, const semanage_user_key_t * key, semanage_user_t ** response); extern int semanage_user_exists(semanage_handle_t * handle, const semanage_user_key_t * key, int *response); extern int semanage_user_count(semanage_handle_t * handle, unsigned int *response); extern int semanage_user_iterate(semanage_handle_t * handle, int (*handler) (const semanage_user_t * record, void *varg), void *handler_arg); extern int semanage_user_list(semanage_handle_t * handle, semanage_user_t *** records, unsigned int *count); #endif libsemanage-2.3/man/000077500000000000000000000000001233221606300143765ustar00rootroot00000000000000libsemanage-2.3/man/Makefile000066400000000000000000000003651233221606300160420ustar00rootroot00000000000000# Installation directories. MAN3DIR ?= $(DESTDIR)/usr/share/man/man3 MAN5DIR ?= $(DESTDIR)/usr/share/man/man5 all: install: all mkdir -p $(MAN3DIR) mkdir -p $(MAN5DIR) install -m 644 man3/*.3 $(MAN3DIR) install -m 644 man5/*.5 $(MAN5DIR) libsemanage-2.3/man/man3/000077500000000000000000000000001233221606300152345ustar00rootroot00000000000000libsemanage-2.3/man/man3/semanage_bool.3000066400000000000000000000064531233221606300201230ustar00rootroot00000000000000.TH semanage_bool 3 "16 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_bool \- SELinux Policy Booleans Management API .SH "SYNOPSIS" .B #include .br .B #include .br .B #include .br .B #include .PP This object contains properties associated with a SELinux policy boolean .PP For details on a specific function, see its manual page. .SH "Record API Overview" .HP .BR semanage_bool_create "(3)" \- .br create a boolean .HP .BR semanage_bool_free "(3)" \- .br release resources for this boolean .HP .BR semanage_bool_key_create "(3)" \- .br create a key, which can be used to identify a boolean .HP .BR semanage_bool_key_free "(3)" \- .br release resources for this boolean key .HP .BR semanage_bool_key_extract "(3)" \- .br create a key matching this boolean .HP .BR semanage_bool_clone "(3)" \- .br create an identical boolean (deep-copy clone) .HP .BR semanage_bool_compare "(3)" \- .br compare this boolean to the provided key .HP .BR semanage_bool_compare2 "(3)" \- .br compare this boolean to another .SH "Properties API Overview" .HP .BR semanage_bool_get_name "(3)" \- .br return the name of this boolean .HP .BR semanage_bool_set_name "(3)" \- .br set the name of this boolean .HP .BR semanage_bool_get_value "(3)" \- .br return the value of this boolean .HP .BR semanage_bool_set_value "(3)" \- .br set the value of this boolean .SH "Record Store API Overview" .HP .BR semanage_bool_modify_local "(3)" \- .br add or update a boolean in the local store .HP .BR semanage_bool_set_active "(3)" \- .br update a boolean in the currently active policy .HP .BR semanage_bool_del_local "(3)" \- .br delete a boolean from the local store .HP .BR semanage_bool_exists "(3)" \- .br check if a boolean is defined in the persistent policy .HP .BR semanage_bool_exists_local "(3)" \- .br check if a boolean is defined in the local store .HP .BR semanage_bool_exists_active "(3)" \- .br check if a boolean is defined in the currently active policy .HP .BR semanage_bool_query "(3)" \- .br query a boolean in the persistent policy .HP .BR semanage_bool_query_local "(3)" \- .br query a boolean in the local store .HP .BR semanage_bool_query_active "(3)" \- .br query a boolean in the currently active policy .HP .BR semanage_bool_count "(3)" \- .br count the number of booleans defined in the persistent policy .HP .BR semanage_bool_count_local "(3)" \- .br count the number of booleans defined in the local store .HP .BR semanage_bool_count_active "(3)" \- .br count the number of booleans defined in the currently active policy .HP .BR semanage_bool_iterate "(3)" \- .br execute a callback for each boolean in the persistent policy .HP .BR semanage_bool_iterate_local "(3)" \- .br execute a callback for each boolean in the local store .HP .BR semanage_bool_iterate_active "(3)" \- .br execute a callback for each boolean in the currently active policy .HP .BR semanage_bool_list "(3)" \- .br return an array containing all booleans in the persistent policy .HP .BR semanage_bool_list_local "(3)" \- .br return an array containing all booleans in the local store .HP .BR semanage_bool_list_active "(3)" \- .br return an array containing all booleans in the currently active policy libsemanage-2.3/man/man3/semanage_bool_count.3000066400000000000000000000000321233221606300213160ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_bool_count_active.3000066400000000000000000000000321233221606300226510ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_bool_count_local.3000066400000000000000000000000321233221606300224700ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_bool_del_local.3000066400000000000000000000000301233221606300221020ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-2.3/man/man3/semanage_bool_exists.3000066400000000000000000000000331233221606300215060ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_bool_exists_active.3000066400000000000000000000000331233221606300230410ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_bool_exists_local.3000066400000000000000000000000331233221606300226600ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_bool_iterate.3000066400000000000000000000000341233221606300216250ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_bool_iterate_active.3000066400000000000000000000000341233221606300231600ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_bool_iterate_local.3000066400000000000000000000000341233221606300227770ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_bool_list.3000066400000000000000000000000311233221606300211400ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_bool_list_active.3000066400000000000000000000000311233221606300224730ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_bool_list_local.3000066400000000000000000000000311233221606300223120ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_bool_modify_local.3000066400000000000000000000000331233221606300226300ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-2.3/man/man3/semanage_bool_query.3000066400000000000000000000000321233221606300213330ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_bool_query_active.3000066400000000000000000000000321233221606300226660ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_bool_query_local.3000066400000000000000000000000321233221606300225050ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_bool_set_active.3000066400000000000000000000030671233221606300223270ustar00rootroot00000000000000.TH semanage_bool_set_local 3 "4 January 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_bool_set_active \- update an existing SELinux boolean in the currently active policy .SH "SYNOPSIS" .B #include .br .sp .B extern int semanage_bool_set_active ( .br .BI " semanage_handle_t *" handle "," .br .BI " const semanage_bool_key_t *" key "," .br .BI " const semanage_bool_t *" data ");" .SH "DESCRIPTION" .TP .B Behavior: The set function will fail if no matching key is found in the local store. Otherwise, the provided object will replace the current one. When .BR semanage_commit "(3)" is invoked, changes will be written permanently into the local store, and will be loaded into policy. Validity of the object being added is checked at commit time. .TP .B Parameters: The .I handle is used to track persistent state across semanage calls, and for error reporting. The .I key identifies the .I data object, which will be written into the store. The key are data are properties of the caller, and are not stored or modified internally. .TP .B Requirements: This function requires an semanage connection to be established (see .BR semanage_connect "(3)" ), and must be executed in a transaction (see .BR semanage_begin_transaction "(3)" ). .SH "RETURN VALUE" In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error. Otherwise 0 is returned. .SH "SEE ALSO" .BR semanage_handle_create "(3), " semanage_begin_transaction "(3), " semanage_connect "(3), " semanage_commit "(3). " libsemanage-2.3/man/man3/semanage_count.3000066400000000000000000000022431233221606300203110ustar00rootroot00000000000000.TH semanage_count 3 "16 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_count \- SELinux Management API .SH "SYNOPSIS" The following count function is supported for any semanage record. .br Replace the function and object name as necessary. .B extern int COUNT_FUNCTION ( .br .BI " semanage_handle_t *" handle "," .br .BI " unsigned int* " response ");" .SH "DESCRIPTION" .TP .B Behavior: The count function will return the number of all objects in the selected location. .TP .B Parameters: The .I handle is used to track persistent state across semanage calls, and for error reporting. The number of objects will be stored at the location poined by .I response. .TP .B Requirements: This function requires an semanage connection to be established (see .BR semanage_connect "(3)" ) .SH "RETURN VALUE" In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error. Otherwise a non-negative integer is returned (a commit number). The same number will be returned by all other semanage object read calls until the next commit. .SH "SEE ALSO" .BR semanage_handle_create "(3), " semanage_connect "(3), " libsemanage-2.3/man/man3/semanage_del.3000066400000000000000000000027711233221606300177330ustar00rootroot00000000000000.TH semanage_del 3 "16 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_del \- SELinux Management API .SH "SYNOPSIS" The following delete function is supported for any semanage record. .br Replace the function and object name as necessary. .B extern int DELETE_FUNCTION ( .br .BI " semanage_handle_t *" handle "," .br .BI " const semanage_OBJECT_key_t *" key ");" .SH "DESCRIPTION" .TP .B Behavior: The delete function will remove the object corresponding to the provided key from the local store. If no match is found, no action is taken. Changes will become permanent when .BR semanage_commit "(3)" is invoked. Additional checks may be performed at that time to ensure the system is left in a valid state. .TP .B Parameters: The .I handle is used to track persistent state across semanage calls, and for error reporting. The .I key identifies the .I data object, which will be deleted from the local store. The key is a property of the caller, and will not be stored or modified internally. .TP .B Requirements: This function requires an semanage connection to be established (see .BR semanage_connect "(3)" ), and must be executed in a transaction (see .BR semanage_begin_transaction "(3)" ). .SH "RETURN VALUE" In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error. Otherwise 0 is returned. .SH "SEE ALSO" .BR semanage_handle_create "(3), " semanage_begin_transaction "(3), " semanage_connect "(3), " semanage_commit "(3). " libsemanage-2.3/man/man3/semanage_exists.3000066400000000000000000000025561233221606300205070ustar00rootroot00000000000000.TH semanage_exists 3 "16 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_exists \- SELinux Management API .SH "SYNOPSIS" The following exists function is supported for any semanage record. .br Replace the function and object name as necessary. .B extern int EXISTS_FUNCTION ( .br .BI " semanage_handle_t *" handle "," .br .BI " const semanage_OBJECT_key_t *" key "," .br .BI " semanage_OBJECT_t **" response ");" .SH "DESCRIPTION" .TP .B Behavior: The exists function will return 0 if a matching key is not found, and 1 otherwise. .TP .B Parameters: The .I handle is used to track persistent state across semanage calls, and for error reporting. The .I key identifies the object being checked. The result of the test will be stored in the address pointed by .I response The key is a property of the caller, and will not be stored or modified internally. .TP .B Requirements: This function requires an semanage connection to be established (see .BR semanage_connect "(3)" ) .SH "RETURN VALUE" In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error. Otherwise a non-negative integer is returned (a commit number). The same number will be returned by all other read calls to the semanage database until the next commit. .SH "SEE ALSO" .BR semanage_handle_create "(3), " semanage_connect "(3), " libsemanage-2.3/man/man3/semanage_fcontext.3000066400000000000000000000064671233221606300210270ustar00rootroot00000000000000.TH semanage_fcontext 3 "16 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_fcontext \- SELinux File Context Management API .SH "SYNOPSIS" .B #include .br .B #include .br .B #include .PP This object contains properties associated with a SELinux file context specification .PP For details on a specific function, see its manual page. .SH "Record API Overview" .HP .BR semanage_fcontext_create "(3)" \- .br create a file context spec .HP .BR semanage_fcontext_free "(3)" \- .br release resources for this file context spec .HP .BR semanage_fcontext_key_create "(3)" \- .br create a key, which can be used to identify a file context spec .HP .BR semanage_fcontext_key_free "(3)" \- .br release resources for this file context spec key .HP .BR semanage_fcontext_key_extract "(3)" \- .br create a key matching this file context spec .HP .BR semanage_fcontext_clone "(3)" \- .br create an identical file context spec (deep-copy clone) .HP .BR semanage_fcontext_compare "(3)" \- .br compare this file context spec to the provided key .HP .BR semanage_fcontext_compare2 "(3)" \- .br compare this file context spec to another .SH "Properties API Overview" .HP .BR semanage_fcontext_get_expr "(3)" \- .br return the regular expression for this file context spec .HP .BR semanage_fcontext_set_expr "(3)" \- .br set the regular expression for this file context spec .HP .BR semanage_fcontext_get_type "(3)" \- .br return the file type for this file context spec .HP .BR semanage_fcontext_get_type_str "(3)" \- .br return a string representation for this file context spec type .HP .BR semanage_fcontext_set_type "(3)" \- .br set the file type for this file context spec .HP .BR semanage_fcontext_get_con "(3)" \- .br return the SELinux context for this file context spec .HP .BR semanage_fcontext_set_expr "(3)" \- .br set the SELinux context for this file context spec .SH "Record Store API Overview" .HP .BR semanage_fcontext_modify_local "(3)" \- .br add or update a file context spec in the local store .HP .BR semanage_fcontext_del_local "(3)" \- .br delete a file context spec from the local store .HP .BR semanage_fcontext_exists "(3)" \- .br check if a file context spec is defined in the persistent policy .HP .BR semanage_fcontext_exists_local "(3)" \- .br check if a file context spec is defined in the local store .HP .BR semanage_fcontext_query "(3)" \- .br query a file context spec in the persistent policy .HP .BR semanage_fcontext_query_local "(3)" \- .br query a file context spec in the local store .HP .BR semanage_fcontext_count "(3)" \- .br count the number of file context specs defined in the persistent policy .HP .BR semanage_fcontext_count_local "(3)" \- .br count the number of file context specs defined in the local store .HP .BR semanage_fcontext_iterate "(3)" \- .br execute a callback for each file context spec in the persistent policy .HP .BR semanage_fcontext_iterate_local "(3)" \- .br execute a callback for each file context spec in the local store .HP .BR semanage_fcontext_list "(3)" \- .br return an array containing all file context specs in the persistent policy .HP .BR semanage_fcontext_list_local "(3)" \- .br return an array containing all file context specs in the local store libsemanage-2.3/man/man3/semanage_fcontext_count.3000066400000000000000000000000321233221606300222150ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_fcontext_count_local.3000066400000000000000000000000321233221606300233670ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_fcontext_del_local.3000066400000000000000000000000301233221606300230010ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-2.3/man/man3/semanage_fcontext_exists.3000066400000000000000000000000331233221606300224050ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_fcontext_exists_local.3000066400000000000000000000000331233221606300235570ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_fcontext_iterate.3000066400000000000000000000000341233221606300225240ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_fcontext_iterate_local.3000066400000000000000000000000341233221606300236760ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_fcontext_list.3000066400000000000000000000000311233221606300220370ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_fcontext_list_local.3000066400000000000000000000000311233221606300232110ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_fcontext_modify_local.3000066400000000000000000000000331233221606300235270ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-2.3/man/man3/semanage_fcontext_query.3000066400000000000000000000000321233221606300222320ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_fcontext_query_local.3000066400000000000000000000000321233221606300234040ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_iface.3000066400000000000000000000057451233221606300202420ustar00rootroot00000000000000.TH semanage_iface 3 "16 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_iface \- SELinux Network Interfaces Management API .SH "SYNOPSIS" .B #include .br .B #include .br .B #include .PP This object contains properties associated with a network interface. .PP For details on a specific function, see its manual page. .SH "Record API Overview" .HP .BR semanage_iface_create "(3)" \- .br create an interface .HP .BR semanage_iface_free "(3)" \- .br release resources for this interface .HP .BR semanage_iface_key_create "(3)" \- .br create a key, which can be used to identify an interface .HP .BR semanage_iface_key_free "(3)" \- .br release resources for this interface key .HP .BR semanage_iface_key_extract "(3)" \- .br create a key matching this interface .HP .BR semanage_iface_clone "(3)" \- .br create an identical interface (deep-copy clone) .HP .BR semanage_iface_compare "(3)" \- .br compare this interface to the provided key .HP .BR semanage_iface_compare2 "(3)" \- .br compare this interface to another .SH "Properties API Overview" .HP .BR semanage_iface_get_name "(3)" \- .br return the name of this interface .HP .BR semanage_iface_set_name "(3)" \- .br set the name of this interface .HP .BR semanage_iface_get_ifcon "(3)" \- .br return the SELinux context associated with this interface .HP .BR semanage_iface_set_ifcon "(3)" \- .br set the SELinux context associated with this interface .HP .BR semanage_iface_get_msgcon "(3)" \- .br return the SELinux context associated with packets sent over this interface .HP .BR semanage_iface_set_msgcon "(3)" \- .br set the SELinux context associated with packets sent over this interface .SH "Record Store API Overview" .HP .BR semanage_iface_modify_local "(3)" \- .br add or update an interface in the local store .HP .BR semanage_iface_del_local "(3)" \- .br delete an interface from the local store .HP .BR semanage_iface_exists "(3)" \- .br check if an interface is defined in the persistent policy .HP .BR semanage_iface_exists_local "(3)" \- .br check if an interface is defined in the local store .HP .BR semanage_iface_query "(3)" \- .br query an interface in the persistent policy .HP .BR semanage_iface_query_local "(3)" \- .br query an interface in the local store .HP .BR semanage_iface_count "(3)" \- .br count the number of interfaces defined in the persistent policy .HP .BR semanage_iface_count_local "(3)" \- .br count the number of interfaces defined in the local store .HP .BR semanage_iface_iterate "(3)" \- .br execute a callback for each interface in the persistent policy .HP .BR semanage_iface_iterate_local "(3)" \- .br execute a callback for each interface in the local store .HP .BR semanage_iface_list "(3)" \- .br return an array containing all interfaces in the persistent policy .HP .BR semanage_iface_list_local "(3)" \- .br return an array containing all interfaces in the local store libsemanage-2.3/man/man3/semanage_iface_count.3000066400000000000000000000000321233221606300214320ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_iface_count_local.3000066400000000000000000000000321233221606300226040ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_iface_del_local.3000066400000000000000000000000301233221606300222160ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-2.3/man/man3/semanage_iface_exists.3000066400000000000000000000000331233221606300216220ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_iface_exists_local.3000066400000000000000000000000331233221606300227740ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_iface_iterate.3000066400000000000000000000000341233221606300217410ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_iface_iterate_local.3000066400000000000000000000000341233221606300231130ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_iface_list.3000066400000000000000000000000311233221606300212540ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_iface_list_local.3000066400000000000000000000000311233221606300224260ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_iface_modify_local.3000066400000000000000000000000331233221606300227440ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-2.3/man/man3/semanage_iface_query.3000066400000000000000000000000321233221606300214470ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_iface_query_local.3000066400000000000000000000000321233221606300226210ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_iterate.3000066400000000000000000000041411233221606300206150ustar00rootroot00000000000000.TH semanage_iterate 3 "15 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_iterate \- SELinux Management API .SH "SYNOPSIS" The following iterate function is supported for any semanage record. .br Replace the function and object name as necessary. .B extern int ITERATE_FUNCTION ( .br .BI " semanage_handle_t *" handle "," .br .BI " int (*handler) ( .br .BI " const semanage_OBJECT_t *" object "," .br .BI " void *" varg ")," .br .BI " void *" handler_arg ");" .SH "DESCRIPTION" .TP .B Behavior: The iterate function will execute the specified handler over all objects in the selected location. An arbitrary argument can be passed into the handler function along with each object. The object passed in is property of the libsemanage library, and may not be modified or preserved - use .B semanage_OBJECT_clone if that is necessary. The handler code may not invoke any semanage write requests for the same object type (i.e. modifying the underlying store is not allowed). The iterate function is reentrant only while inside a transaction (see .B semanage_begin_transaction ). It is not safe to execute other semanage read or write requests within iterate if not inside a transaction. The handler may return \-1 to signal error exit, 0 to signal continue, and 1 to signal successful exit early (the iterate function will stop accordingly). .TP .B Parameters: The .I handle is used to track persistent state across semanage calls, and for error reporting. The .I handler is the function to execute, with .I handler_arg as its second parameter, and each object as its first parameter. .TP .B Requirements: This function requires an semanage connection to be established (see .BR semanage_connect "(3)" ) .SH "RETURN VALUE" In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error. Otherwise a non-negative integer is returned (a commit number). The same number will be returned by all other semanage object read calls until the next commit. .SH "SEE ALSO" .BR semanage_handle_create "(3), " semanage_connect "(3), " libsemanage-2.3/man/man3/semanage_list.3000066400000000000000000000027121233221606300201350ustar00rootroot00000000000000.TH semanage_list 3 "16 March 2006" "ivg2@cornell.edu" "SELinux managent API documentation" .SH "NAME" semanage_list \- SELinux Lists Management API .SH "SYNOPSIS" The following list function is supported for any SELinux managent record. .br Replace the function and object name as necessary. .B extern int LIST_FUNCTION ( .br .BI " semanage_handle_t *" handle "," .br .BI " semanage_OBJECT_t ***" objects "," .br .BI " unsigned int* " count ");" .SH "DESCRIPTION" .TP .B Behavior: The list function will return an array of all the objects in the selected location. .TP .B Parameters: The .I handle is used to track persistent state across semanage calls, and for error reporting. The function will allocate and populate the the array of objects, and store it at the location pointed by .I objects. It will write the number of objects at the location pointed by .I count. The array, and all its objects become property of the caller. Each object must be freed with .B semanage_OBJECT_free. .TP .B Requirements: This function requires an semanage connection to be established (see .BR semanage_connect "(3)" ) .SH "RETURN VALUE" In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error. Otherwise a non-negative integer is returned (a commit number). The same number will be returned by all other semanage object read calls until the next commit. .SH "SEE ALSO" .BR semanage_handle_create "(3), " semanage_connect "(3), " libsemanage-2.3/man/man3/semanage_modify.3000066400000000000000000000033431233221606300204520ustar00rootroot00000000000000.TH semanage_modify 3 "16 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_modify \- SELinux Management API .SH "SYNOPSIS" The following modify function is supported for any semanage record. .br Replace the function and object name as necessary. .B extern int MODIFY_FUNCTION ( .br .BI " semanage_handle_t *" handle "," .br .BI " const semanage_OBJECT_key_t *" key "," .br .BI " const semanage_OBJECT_t *" data ");" .SH "DESCRIPTION" .TP .B Behavior: If a matching key is found in the local store, the provided object will replace the current one. Otherwise, it will be added to the store. When .BR semanage_commit "(3)" is invoked, changes will be permanently written into the local store, and then loaded into policy. Validity of the object being added is checked at commit time. Adding new objects with respect to policy is allowed, except in the case of booleans. Attempt to add new booleans with respect to policy will fail at commit time. .TP .B Parameters: The .I handle is used to track persistent state across semanage calls, and for error reporting. The .I key identifies the .I data object, which will be written into the store. The key are data are properties of the caller, and are not stored or modified internally. .TP .B Requirements: This function requires an semanage connection to be established (see .BR semanage_connect "(3)" ), and must be executed in a transaction (see .BR semanage_begin_transaction "(3)" ). .SH "RETURN VALUE" In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error. Otherwise 0 is returned. .SH "SEE ALSO" .BR semanage_handle_create "(3), " semanage_begin_transaction "(3), " semanage_connect "(3), " semanage_commit "(3). " libsemanage-2.3/man/man3/semanage_node.3000066400000000000000000000073231233221606300201120ustar00rootroot00000000000000.TH semanage_node 3 "16 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_node \- SELinux Network Nodes Management API .SH "SYNOPSIS" .B #include .br .B #include .br .B #include .PP This object contains properties associated with a network node. .PP For details on a specific function, see its manual page. .SH "Record API Overview" .HP .BR semanage_node_create "(3)" \- .br create a node .HP .BR semanage_node_free "(3)" \- .br release resources for this node .HP .BR semanage_node_key_create "(3)" \- .br create a key, which can be used to identify a node .HP .BR semanage_node_key_free "(3)" \- .br release resources for this node key .HP .BR semanage_node_key_extract "(3)" \- .br create a key matching this node .HP .BR semanage_node_clone "(3)" \- .br create an identical node (deep-copy clone) .HP .BR semanage_node_compare "(3)" \- .br compare this node to the provided key .HP .BR semanage_node_compare2 "(3)" \- .br compare this node to another .SH "Properties API Overview" .HP .BR semanage_node_get_addr "(3)" \- .br return the IP address of this node in string representation .HP .BR semanage_node_set_addr "(3)" \- .br set the IP address of this node from the provided string representation and protocol .HP .BR semanage_node_get_addr_bytes "(3)" \- .br return the IP address of this node as a byte array in network byte order .HP .BR semanage_node_set_addr_bytes "(3)" \- .br set the IP address of this node from the provided byte array in network byte order .HP .BR semanage_node_get_mask "(3)" \- .br return the IP mask of this node in string representation .HP .BR semanage_node_set_mask "(3)" \- .br set the IP mask of this node from the provided string representation and protocol version .HP .BR semanage_node_get_mask_bytes "(3)" \- .br return the IP mask of this node as a byte array in network byte order .HP .BR semanage_node_set_mask_bytes "(3)" \- .br set the IP mask of this node from the provided byte array in network byte order .HP .BR semanage_node_get_proto "(3)" \- .br return the IP protocol version for this node .HP .BR semanage_node_get_proto_str "(3)" \- .br return a string representation of the given node protocol .HP .BR semanage_node_set_proto "(3)" \- .br set the IP protocol version for this node .HP .BR semanage_node_get_con "(3)" \- .br return the SELinux context associated with this node .HP .BR semanage_node_set_con "(3)" \- .br set the SELinux context associated with this node .SH "Record Store API Overview" .HP .BR semanage_node_modify_local "(3)" \- .br add or update an interface in the local store .HP .BR semanage_node_del_local "(3)" \- .br delete an interface from the local store .HP .BR semanage_node_exists "(3)" \- .br check if an interface is defined in the persistent policy .HP .BR semanage_node_exists_local "(3)" \- .br check if an interface is defined in the local store .HP .BR semanage_node_query "(3)" \- .br query an interface in the persistent policy .HP .BR semanage_node_query_local "(3)" \- .br query an interface in the local store .HP .BR semanage_node_count "(3)" \- .br count the number of nodes defined in the persistent policy .HP .BR semanage_node_count_local "(3)" \- .br count the number of nodes defined in the local store .HP .BR semanage_node_iterate "(3)" \- .br execute a callback for each interface in the persistent policy .HP .BR semanage_node_iterate_local "(3)" \- .br execute a callback for each interface in the local store .HP .BR semanage_node_list "(3)" \- .br return an array containing all nodes in the persistent policy .HP .BR semanage_node_list_local "(3)" \- .br return an array containing all nodes in the local store libsemanage-2.3/man/man3/semanage_node_count.3000066400000000000000000000000321233221606300213100ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_node_count_local.3000066400000000000000000000000321233221606300224620ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_node_del_local.3000066400000000000000000000000301233221606300220740ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-2.3/man/man3/semanage_node_exists.3000066400000000000000000000000331233221606300215000ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_node_exists_local.3000066400000000000000000000000331233221606300226520ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_node_iterate.3000066400000000000000000000000341233221606300216170ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_node_iterate_local.3000066400000000000000000000000341233221606300227710ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_node_list.3000066400000000000000000000000311233221606300211320ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_node_list_local.3000066400000000000000000000000311233221606300223040ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_node_modify_local.3000066400000000000000000000000331233221606300226220ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-2.3/man/man3/semanage_node_query.3000066400000000000000000000000321233221606300213250ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_node_query_local.3000066400000000000000000000000321233221606300224770ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_port.3000066400000000000000000000062711233221606300201520ustar00rootroot00000000000000.TH semanage_port 3 "16 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_port \- SELinux Network Ports Management API .SH "SYNOPSIS" .B #include .br .B #include .br .B #include .PP This object contains properties associated with a range of network ports. .PP For details on a specific function, see its manual page. .SH "Record API Overview" .HP .BR semanage_port_create "(3)" \- .br create a port range .HP .BR semanage_port_free "(3)" \- .br release resources for this port range .HP .BR semanage_port_key_create "(3)" \- .br create a key, which can be used to identify a port range .HP .BR semanage_port_key_free "(3)" \- .br release resources for this port range key .HP .BR semanage_port_key_extract "(3)" \- .br create a key matching this port range .HP .BR semanage_port_clone "(3)" \- .br create an identical port range (deep-copy clone) .HP .BR semanage_port_compare "(3)" \- .br compare this port range to the provided key .HP .BR semanage_port_compare2 "(3)" \- .br compare this port range to another .SH "Properties API Overview" .HP .BR semanage_port_get_proto "(3)" \- .br return the protocol for this port range .HP .BR semanage_port_get_proto_str "(3)" \- .br return a string representation of the given port protocol .HP .BR semanage_port_set_proto "(3)" \- .br set the protocol for this port range .HP .BR semanage_port_get_low "(3)" \- .br return the low port number for this port range .HP .BR semanage_port_get_high "(3)" \- .br return the high port number for this port range .HP .BR semanage_port_set_port "(3)" \- .br set the port number (same low and high) for this port range .HP .BR semanage_port_set_range "(3)" \- .br set the low and high port number for this port range .HP .BR semanage_port_get_con "(3)" \- .br return the SELinux context for this port range .HP .BR semanage_port_set_con "(3)" \- .br set the SELinux context for this port range .SH "Record Store API Overview" .HP .BR semanage_port_modify_local "(3)" \- .br add or update a port range in the local store .HP .BR semanage_port_del_local "(3)" \- .br delete a port range from the local store .HP .BR semanage_port_exists "(3)" \- .br check if a port range is defined in the persistent policy .HP .BR semanage_port_exists_local "(3)" \- .br check if a port range is defined in the local store .HP .BR semanage_port_query "(3)" \- .br query a port range in the persistent policy .HP .BR semanage_port_query_local "(3)" \- .br query a port range in the local store .HP .BR semanage_port_count "(3)" \- .br count the number of port ranges defined in the persistent policy .HP .BR semanage_port_count_local "(3)" \- .br count the number of port ranges defined in the local store .HP .BR semanage_port_iterate "(3)" \- .br execute a callback for each port range in the persistent policy .HP .BR semanage_port_iterate_local "(3)" \- .br execute a callback for each port range in the local store .HP .BR semanage_port_list "(3)" \- .br return an array containing all port ranges in the persistent policy .HP .BR semanage_port_list_local "(3)" \- .br return an array containing all port ranges in the local store libsemanage-2.3/man/man3/semanage_port_count.3000066400000000000000000000000321233221606300213470ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_port_count_local.3000066400000000000000000000000321233221606300225210ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_port_del_local.3000066400000000000000000000000301233221606300221330ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-2.3/man/man3/semanage_port_exists.3000066400000000000000000000000331233221606300215370ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_port_exists_local.3000066400000000000000000000000331233221606300227110ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_port_iterate.3000066400000000000000000000000341233221606300216560ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_port_iterate_local.3000066400000000000000000000000341233221606300230300ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_port_list.3000066400000000000000000000000311233221606300211710ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_port_list_local.3000066400000000000000000000000311233221606300223430ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_port_modify_local.3000066400000000000000000000000331233221606300226610ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-2.3/man/man3/semanage_port_query.3000066400000000000000000000000321233221606300213640ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_port_query_local.3000066400000000000000000000000321233221606300225360ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_query.3000066400000000000000000000027221233221606300203300ustar00rootroot00000000000000.TH semanage_query 3 "15 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_query \- SELinux Management API .SH "SYNOPSIS" The following query function is supported for any semanage record. .br Replace the function and object name as necessary. .B extern int QUERY_FUNCTION ( .br .BI " semanage_handle_t *" handle "," .br .BI " const semanage_OBJECT_key_t *" key "," .br .BI " semanage_OBJECT_t **" response ");" .SH "DESCRIPTION" .TP .B Behavior: The query function will fail if a matching key is not found. Otherwise, the corresponding object is returned. .TP .B Parameters: The .I handle is used to track persistent state across semanage calls, and for error reporting. The .I key identifies the object being queried, which will be stored in the address pointed by .I response The key is a property of the caller, and will not be stored or modified internally. The object returned becomes a property of the caller, and must be freed with .B semanage_OBJECT_free. .TP .B Requirements: This function requires an semanage connection to be established (see .BR semanage_connect "(3)" ) .SH "RETURN VALUE" In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error. Otherwise a non-negative integer is returned (a commit number). The same number will be returned by all other semanage object read calls until the next commit. .SH "SEE ALSO" .BR semanage_handle_create "(3), " semanage_connect "(3), " libsemanage-2.3/man/man3/semanage_set_root.3000066400000000000000000000011601233221606300210140ustar00rootroot00000000000000.TH semanage_set_root 3 "1 June 2011" "dwalsh@redhat.com" "Libsemanage API documentation" .SH "NAME" semanage_set_root \- SELinux Management API .SH "SYNOPSIS" Set the alternate root directory for SELinux configuration directory. .B #include .B extern const char *semanage_set_root(const char *path); .SH "DESCRIPTION" .TP This function sets an alternate root directory to for SELinux configuration paths to be used by the semanage library. .SH "RETURN VALUE" In case of failure, \-1 is returned. Otherwise 0 is returned. .SH "SEE ALSO" .BR semanage_handle_create "(3), " semanage_connect "(3), " libsemanage-2.3/man/man3/semanage_seuser.3000066400000000000000000000060511233221606300204700ustar00rootroot00000000000000.TH semanage_seuser 3 "16 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_seuser \- Linux UID to SELinux User Management API .SH "SYNOPSIS" .B #include .br .B #include .br .B #include .PP This object contains properties associated with a Unix user. Typically many Unix users are mapped to the same SELinux user. See .BR semanage_user "(3)" for overview of the SELinux user API. .PP For details on a specific function, see its manual page. .SH "Record API Overview" .HP .BR semanage_seuser_create "(3)" \- .br create a seuser .HP .BR semanage_seuser_free "(3)" \- .br release resources for this seuser .HP .BR semanage_seuser_key_create "(3)" \- .br create a key, which can be used to identify a seuser .HP .BR semanage_seuser_key_free "(3)" \- .br release resources for this seuser key .HP .BR semanage_seuser_key_extract "(3)" \- .br create a key matching this seuser .HP .BR semanage_seuser_clone "(3)" \- .br create an identical seuser (deep-copy clone) .HP .BR semanage_seuser_compare "(3)" \- .br compare this seuser to the provided key .HP .BR semanage_seuser_compare2 "(3)" \- .br compare this seuser to another .SH "Properties API Overview" .HP .BR semanage_seuser_get_name "(3)" \- .br return the name of this seuser .HP .BR semanage_user_set_name "(3)" \- .br set the name of this seuser .HP .BR semanage_seuser_get_sename "(3)" \- .br return the name of the (SELinux) user mapped to this seuser .HP .BR semanage_user_set_sename "(3)" \- .br set the name of the (SELinux) user mapped to this seuser .HP .BR semanage_user_get_mlsrange "(3)" \- .br return a the range of valid MLS sensitivities and categories for this user .HP .BR semanage_user_set_mlsrange "(3)" \- .br set the range of valid MLS sensitivities and categories for this user .SH "Record Store API Overview" .HP .BR semanage_seuser_modify_local "(3)" \- .br add or update a seuser in the local store .HP .BR semanage_seuser_del_local "(3)" \- .br delete a seuser from the local store .HP .BR semanage_seuser_exists "(3)" \- .br check if a seuser is defined in the persistent policy .HP .BR semanage_seuser_exists_local "(3)" \- .br check if a seuser is defined in the local store .HP .BR semanage_seuser_query "(3)" \- .br query a seuser in the persistent policy .HP .BR semanage_seuser_query_local "(3)" \- .br query a seuser in the local store .HP .BR semanage_seuser_count "(3)" \- .br count the number of seusers defined in the persistent policy .HP .BR semanage_seuser_count_local "(3)" \- .br count the number of seusers defined in the local store .HP .BR semanage_seuser_iterate "(3)" \- .br execute a callback for each seuser in the persistent policy .HP .BR semanage_seuser_iterate_local "(3)" \- .br execute a callback for each seuser in the local store .HP .BR semanage_seuser_list "(3)" \- .br return an array containing all seusers in the persistent policy .HP .BR semanage_seuser_list_local "(3)" \- .br return an array containing all seusers in the local store libsemanage-2.3/man/man3/semanage_seuser_count.3000066400000000000000000000000321233221606300216710ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_seuser_count_local.3000066400000000000000000000000321233221606300230430ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_seuser_del_local.3000066400000000000000000000000301233221606300224550ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-2.3/man/man3/semanage_seuser_exists.3000066400000000000000000000000331233221606300220610ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_seuser_exists_local.3000066400000000000000000000000331233221606300232330ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_seuser_iterate.3000066400000000000000000000000341233221606300222000ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_seuser_iterate_local.3000066400000000000000000000000341233221606300233520ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_seuser_list.3000066400000000000000000000000311233221606300215130ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_seuser_list_local.3000066400000000000000000000000311233221606300226650ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_seuser_modify_local.3000066400000000000000000000000331233221606300232030ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-2.3/man/man3/semanage_seuser_query.3000066400000000000000000000000321233221606300217060ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_seuser_query_local.3000066400000000000000000000000321233221606300230600ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_user.3000066400000000000000000000072421233221606300201430ustar00rootroot00000000000000.TH semanage_user 3 "16 March 2006" "ivg2@cornell.edu" "Libsemanage API documentation" .SH "NAME" semanage_user \- SELinux User Management API .SH "SYNOPSIS" .B #include .br .B #include .br .B #include .PP This object contains properties associated with a SELinux user. Typically many Unix users are mapped to the same SELinux user. See .BR semanage_seuser "(3)" for overview of the Unix user API. .PP For details on a specific function, see its manual page. .SH "Record API Overview" .HP .BR semanage_user_create "(3)" \- .br create a user .HP .BR semanage_user_free "(3)" \- .br release resources for this user .HP .BR semanage_user_key_create "(3)" \- .br create a key, which can be used to identify a user .HP .BR semanage_user_key_free "(3)" \- .br release resources for this user key .HP .BR semanage_user_key_extract "(3)" \- .br create a key matching this user .HP .BR semanage_user_clone "(3)" \- .br create an identical user (deep-copy clone) .HP .BR semanage_user_compare "(3)" \- .br compare this user to the provided key .HP .BR semanage_user_compare2 "(3)" \- .br compare this user to another .SH "Properties API Overview" .HP .BR semanage_user_get_name "(3)" \- .br return the name of this user .HP .BR semanage_user_set_name "(3)" \- .br set the name of this user .HP .BR semanage_user_get_prefix "(3)" \- .br return the labeling prefix for this user, used to control the contexts of user directories .HP .BR semanage_user_set_prefix "(3)" \- .br set the labeling prefix for this user .HP .BR semanage_user_get_mlslevel "(3)" \- .br return the default MLS level, which is assigned to this user at login time .HP .BR semanage_user_set_mlslevel "(3)" \- .br set the default MLS level .HP .BR semanage_user_get_mlsrange "(3)" \- .br return the range of valid MLS sensitivities and categories for this user .HP .BR semanage_user_set_mlsrange "(3)" \- .br set the range of valid MLS sensitivities and categories for this user .HP .BR semanage_user_add_role "(3)" \- .br add a role to the user's list of valid roles .HP .BR semanage_user_del_role "(3)" \- .br remove a role from the user's list of valid roles .HP .BR semanage_user_has_role "(3)" \- .br check if a role is valid for this user .HP .BR semanage_user_get_num_roles "(3)" \- .br return the number of valid roles for this user .HP .BR semanage_user_get_roles "(3)" \- .br return an array containing the roles for this user .HP .BR semanage_user_set_roles "(3)" \- set the roles for this user .SH "Record Store API Overview" .HP .BR semanage_user_modify_local "(3)" \- .br add or update a user in the local store .HP .BR semanage_user_del_local "(3)" \- .br delete a user from the local store .HP .BR semanage_user_exists "(3)" \- .br check if a user is defined in the persistent policy .HP .BR semanage_user_exists_local "(3)" \- .br check if a user is defined in the local store .HP .BR semanage_user_query "(3)" \- .br query a user in the persistent policy .HP .BR semanage_user_query_local "(3)" \- .br query a user in the local store .HP .BR semanage_user_count "(3)" \- .br count the number of users defined in the persistent policy .HP .BR semanage_user_count_local "(3)" \- .br count the number of users defined in the local store .HP .BR semanage_user_iterate "(3)" \- .br execute a callback for each user in the persistent policy .HP .BR semanage_user_iterate_local "(3)" \- .br execute a callback for each user in the local store .HP .BR semanage_user_list "(3)" \- .br return an array containing all users in the persistent policy .HP .BR semanage_user_list_local "(3)" \- .br return an array containing all users in the local store libsemanage-2.3/man/man3/semanage_user_count.3000066400000000000000000000000321233221606300213410ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_user_count_local.3000066400000000000000000000000321233221606300225130ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-2.3/man/man3/semanage_user_del_local.3000066400000000000000000000000301233221606300221250ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-2.3/man/man3/semanage_user_exists.3000066400000000000000000000000331233221606300215310ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_user_exists_local.3000066400000000000000000000000331233221606300227030ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-2.3/man/man3/semanage_user_iterate.3000066400000000000000000000000341233221606300216500ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_user_iterate_local.3000066400000000000000000000000341233221606300230220ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-2.3/man/man3/semanage_user_list.3000066400000000000000000000000311233221606300211630ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_user_list_local.3000066400000000000000000000000311233221606300223350ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-2.3/man/man3/semanage_user_modify_local.3000066400000000000000000000000331233221606300226530ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-2.3/man/man3/semanage_user_query.3000066400000000000000000000000321233221606300213560ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man3/semanage_user_query_local.3000066400000000000000000000000321233221606300225300ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-2.3/man/man5/000077500000000000000000000000001233221606300152365ustar00rootroot00000000000000libsemanage-2.3/man/man5/semanage.conf.5000066400000000000000000000075401233221606300200360ustar00rootroot00000000000000.TH semanage.conf "5" "September 2011" "semanage.conf" "Linux System Administration" .SH NAME semanage.conf \- global configuration file for the SELinux Management library .SH DESCRIPTION .PP The .BR semanage.conf file is usually located under the directory /etc/selinux and it is used for run-time configuration of the behavior of the SELinux Management library. .PP Each line should contain a configuration parameter followed by the equal sign ("=") and then followed by the configuration value for that parameter. Anything after the "#" symbol is ignored similarly to empty lines. .PP The following parameters are allowed: .RS .TP .B module-store Specify how the SELinux Management library should interact with the SELinux policy store. When set to "direct", the SELinux Management library writes to the SELinux policy module store directly (this is the default setting). Otherwise a socket path or a server name can be used for the argument. If the argument begins with "/" (as in "/foo/bar"), it represents the path to a named socket that should be used to connect the policy management server. If the argument does not begin with a "/" (as in "foo.com:4242"), it should be interpreted as the name of a remote policy management server to be used through a TCP connection (default port is 4242 unless a different one is specified after the server name using the colon to separate the two fields). .TP .B policy-version When generating the policy, by default .BR semanage will set the policy version to POLICYDB_VERSION_MAX, as defined in . Change this setting if a different version needs to be set for the policy. .TP .B expand-check Whether or not to check "neverallow" rules when executing all .BR semanage command. It can be set to either "0" (disabled) or "1" (enabled) and by default it is enabled. There might be a large penalty in execution time if this option is enabled. .TP .B file-mode By default the permission mode for the run-time policy files is set to 0644. .TP .B save-previous It controls whether the previous module directory is saved after a successful commit to the policy store and it can be set to either "true" or "false". By default it is set to "false" (the previous version is deleted). .TP .B save-linked It controls whether the previously linked module is saved (with name "base.linked") after a successful commit to the policy store. It can be set to either "true" or "false" and by default it is set to "false" (the previous module is deleted). .TP .B ignoredirs List, separated by ";", of directories to ignore when setting up users homedirs. Some distributions use this to stop labeling /root as a homedir. .TP .B usepasswd Whether or not to enable the use getpwent() to obtain a list of home directories to label. It can be set to either "true" or "false". By default it is set to "true". .TP .B disable-genhomedircon It controls whether or not the genhomedircon function is executed when using the .BR semanage command and it can be set to either "false" or "true". By default the genhomedircon functionality is enabled (equivalent to this option set to "false"). .TP .B handle-unknown This option controls the kernel behavior for handling permissions defined in the kernel but missing from the actual policy. It can be set to "deny", "reject" or "allow". .TP .B bzip-blocksize It should be in the range 0-9. A value of 0 means no compression. By default the bzip block size is set to 9 (actual block size value is obtained after multiplication by 100000). .TP .B bzip-small When set to "true", the bzip algorithm shall try to reduce its system memory usage. It can be set to either "true" or "false" and by default it is set to "false". .SH "SEE ALSO" .TP semanage(8) .PP .SH AUTHOR This manual page was written by Guido Trentalancia . The SELinux management library was written by Tresys Technology LLC and Red Hat Inc. libsemanage-2.3/src/000077500000000000000000000000001233221606300144125ustar00rootroot00000000000000libsemanage-2.3/src/.gitignore000066400000000000000000000001311233221606300163750ustar00rootroot00000000000000semanageswig_wrap.c semanageswig_python_exception.i semanage.py semanageswig_ruby_wrap.c libsemanage-2.3/src/Makefile000066400000000000000000000122631233221606300160560ustar00rootroot00000000000000# Support building the Python bindings multiple times, against various Python # runtimes (e.g. Python 2 vs Python 3) by optionally prefixing the build # targets with "PYPREFIX": PYTHON ?= python PYPREFIX ?= $(notdir $(PYTHON)) RUBY ?= ruby RUBYPREFIX ?= $(notdir $(RUBY)) # Installation directories. PREFIX ?= $(DESTDIR)/usr LIBDIR ?= $(PREFIX)/lib SHLIBDIR ?= $(PREFIX)/lib INCLUDEDIR ?= $(PREFIX)/include PYLIBVER ?= $(shell $(PYTHON) -c 'import sys;print("python%d.%d" % sys.version_info[0:2])') PYINC ?= $(shell pkg-config --cflags $(PYPREFIX)) PYLIBDIR ?= $(LIBDIR)/$(PYLIBVER) RUBYLIBVER ?= $(shell $(RUBY) -e 'print RUBY_VERSION.split(".")[0..1].join(".")') RUBYPLATFORM ?= $(shell $(RUBY) -e 'print RUBY_PLATFORM') RUBYINC ?= $(shell pkg-config --cflags ruby-$(RUBYLIBVER)) RUBYINSTALL ?= $(LIBDIR)/ruby/site_ruby/$(RUBYLIBVER)/$(RUBYPLATFORM) LIBBASE=$(shell basename $(LIBDIR)) DEFAULT_SEMANAGE_CONF_LOCATION=$(DESTDIR)/etc/selinux/semanage.conf ifeq ($(DEBUG),1) export CFLAGS = -g3 -O0 -gdwarf-2 -fno-strict-aliasing -Wall -Wshadow -Werror export LDFLAGS = -g endif LEX = flex LFLAGS = -s YACC = bison YFLAGS = -d VERSION = $(shell cat ../VERSION) LIBVERSION = 1 LIBA=libsemanage.a TARGET=libsemanage.so LIBPC=libsemanage.pc SWIGIF= semanageswig_python.i semanageswig_python_exception.i SWIGRUBYIF= semanageswig_ruby.i SWIGCOUT= semanageswig_wrap.c SWIGRUBYCOUT= semanageswig_ruby_wrap.c SWIGLOBJ:= $(patsubst %.c,$(PYPREFIX)%.lo,$(SWIGCOUT)) SWIGRUBYLOBJ:= $(patsubst %.c,$(RUBYPREFIX)%.lo,$(SWIGRUBYCOUT)) SWIGSO=$(PYPREFIX)_semanage.so SWIGFILES=$(SWIGSO) semanage.py SWIGRUBYSO=$(RUBYPREFIX)_semanage.so LIBSO=$(TARGET).$(LIBVERSION) GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) semanageswig_python_exception.i SRCS= $(filter-out $(GENERATED),$(wildcard *.c)) OBJS= $(patsubst %.c,%.o,$(SRCS)) conf-scan.o conf-parse.o LOBJS= $(patsubst %.c,%.lo,$(SRCS)) conf-scan.lo conf-parse.lo CFLAGS ?= -Werror -Wall -W -Wundef -Wshadow -Wmissing-noreturn -Wmissing-format-attribute SWIG_CFLAGS += -Wno-error -Wno-unused-but-set-variable -Wno-unused-variable -Wno-shadow \ -Wno-unused-parameter override CFLAGS += -I../include -I$(INCLUDEDIR) -D_GNU_SOURCE RANLIB=ranlib SWIG = swig -Wall -python -o $(SWIGCOUT) -outdir ./ SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./ GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) $(wildcard conf-*.[ch]) all: $(LIBA) $(LIBSO) $(LIBPC) pywrap: all $(SWIGSO) rubywrap: all $(SWIGRUBYSO) $(SWIGLOBJ): $(SWIGCOUT) $(CC) $(CFLAGS) $(SWIG_CFLAGS) $(PYINC) -fPIC -DSHARED -c -o $@ $< $(SWIGRUBYLOBJ): $(SWIGRUBYCOUT) $(CC) $(CFLAGS) $(SWIG_CFLAGS) $(RUBYINC) -fPIC -DSHARED -c -o $@ $< $(SWIGSO): $(SWIGLOBJ) $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $< -L. -lsemanage -L$(LIBDIR) $(SWIGRUBYSO): $(SWIGRUBYLOBJ) $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -L. -lsemanage -L$(LIBDIR) $(LIBA): $(OBJS) $(AR) rcs $@ $^ $(RANLIB) $@ $(LIBSO): $(LOBJS) $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -lsepol -laudit -lselinux -lbz2 -lustr -L$(LIBDIR) -Wl,-soname,$(LIBSO),--version-script=libsemanage.map,-z,defs ln -sf $@ $(TARGET) $(LIBPC): $(LIBPC).in ../VERSION sed -e 's/@VERSION@/$(VERSION)/; s:@prefix@:$(PREFIX):; s:@libdir@:$(LIBBASE):; s:@includedir@:$(INCLUDEDIR):' < $< > $@ semanageswig_python_exception.i: ../include/semanage/semanage.h bash exception.sh > $@ conf-scan.c: conf-scan.l conf-parse.h $(LEX) $(LFLAGS) -t $< > $@ conf-parse.c: conf-parse.y $(YACC) $(YFLAGS) -o $@ $< conf-parse.h: conf-parse.c %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< %.lo: %.c $(CC) $(CFLAGS) -fPIC -DSHARED -c -o $@ $< conf-parse.o: conf-parse.c $(CC) $(filter-out -Werror, $(CFLAGS)) -c -o $@ $< conf-parse.lo: conf-parse.c $(CC) $(filter-out -Werror, $(CFLAGS)) -fPIC -DSHARED -c -o $@ $< conf-scan.o: conf-scan.c $(CC) $(filter-out -Werror, $(CFLAGS)) -c -o $@ $< conf-scan.lo: conf-scan.c $(CC) $(filter-out -Werror, $(CFLAGS)) -fPIC -DSHARED -c -o $@ $< $(SWIGCOUT): $(SWIGIF) $(SWIG) $< $(SWIGRUBYCOUT): $(SWIGRUBYIF) $(SWIGRUBY) $< swigify: $(SWIGIF) $(SWIG) $< install: all test -d $(LIBDIR) || install -m 755 -d $(LIBDIR) install -m 644 $(LIBA) $(LIBDIR) test -d $(SHLIBDIR) || install -m 755 -d $(SHLIBDIR) install -m 755 $(LIBSO) $(SHLIBDIR) test -d $(LIBDIR)/pkgconfig || install -m 755 -d $(LIBDIR)/pkgconfig install -m 644 $(LIBPC) $(LIBDIR)/pkgconfig test -f $(DEFAULT_SEMANAGE_CONF_LOCATION) || install -m 644 -D semanage.conf $(DEFAULT_SEMANAGE_CONF_LOCATION) cd $(LIBDIR) && ln -sf $(LIBSO) $(TARGET) install-pywrap: pywrap test -d $(PYLIBDIR)/site-packages || install -m 755 -d $(PYLIBDIR)/site-packages install -m 755 $(SWIGSO) $(PYLIBDIR)/site-packages/_semanage.so install -m 755 semanage.py $(PYLIBDIR)/site-packages install-rubywrap: rubywrap test -d $(RUBYINSTALL) || install -m 755 -d $(RUBYINSTALL) install -m 755 $(SWIGRUBYSO) $(RUBYINSTALL)/semanage.so relabel: /sbin/restorecon $(SHLIBDIR)/$(LIBSO) clean: -rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(TARGET) conf-parse.c conf-parse.h conf-scan.c *.o *.lo *~ distclean: clean rm -f $(SWIGCOUT) $(SWIGFILES) indent: ../../scripts/Lindent $(filter-out $(GENERATED),$(wildcard *.[ch])) .PHONY: all clean pywrap rubywrap swigify install install-pywrap install-rubywrap distclean libsemanage-2.3/src/boolean_internal.h000066400000000000000000000024541233221606300201030ustar00rootroot00000000000000#ifndef _SEMANAGE_BOOLEAN_INTERNAL_H_ #define _SEMANAGE_BOOLEAN_INTERNAL_H_ #include #include #include #include #include "database.h" #include "handle.h" #include "dso.h" hidden_proto(semanage_bool_clone) hidden_proto(semanage_bool_compare) hidden_proto(semanage_bool_compare2) hidden_proto(semanage_bool_create) hidden_proto(semanage_bool_free) hidden_proto(semanage_bool_get_name) hidden_proto(semanage_bool_get_value) hidden_proto(semanage_bool_key_extract) hidden_proto(semanage_bool_key_free) hidden_proto(semanage_bool_set_name) hidden_proto(semanage_bool_set_value) /* BOOL RECORD: metod table */ extern record_table_t SEMANAGE_BOOL_RTABLE; extern int bool_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig); extern void bool_file_dbase_release(dbase_config_t * dconfig); extern int bool_policydb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig); extern void bool_policydb_dbase_release(dbase_config_t * dconfig); extern int bool_activedb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig); extern void bool_activedb_dbase_release(dbase_config_t * dconfig); #endif libsemanage-2.3/src/boolean_record.c000066400000000000000000000064441233221606300175430ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: semanage_bool_t (Policy Boolean) * Object: semanage_bool_key_t (Policy Boolean Key) * Implements: record_t (Database Record) * Implements: record_key_t (Database Record Key) */ #include typedef sepol_bool_t semanage_bool_t; typedef sepol_bool_key_t semanage_bool_key_t; #define _SEMANAGE_BOOL_DEFINED_ typedef semanage_bool_t record_t; typedef semanage_bool_key_t record_key_t; #define DBASE_RECORD_DEFINED #include "boolean_internal.h" #include "handle.h" #include "database.h" #include #include /* Key */ int semanage_bool_key_create(semanage_handle_t * handle, const char *name, semanage_bool_key_t ** key) { return sepol_bool_key_create(handle->sepolh, name, key); } int semanage_bool_key_extract(semanage_handle_t * handle, const semanage_bool_t * boolean, semanage_bool_key_t ** key) { return sepol_bool_key_extract(handle->sepolh, boolean, key); } hidden_def(semanage_bool_key_extract) void semanage_bool_key_free(semanage_bool_key_t * key) { sepol_bool_key_free(key); } hidden_def(semanage_bool_key_free) int semanage_bool_compare(const semanage_bool_t * boolean, const semanage_bool_key_t * key) { return sepol_bool_compare(boolean, key); } hidden_def(semanage_bool_compare) int semanage_bool_compare2(const semanage_bool_t * boolean, const semanage_bool_t * boolean2) { return sepol_bool_compare2(boolean, boolean2); } hidden_def(semanage_bool_compare2) static int semanage_bool_compare2_qsort(const semanage_bool_t ** boolean, const semanage_bool_t ** boolean2) { return sepol_bool_compare2(*boolean, *boolean2); } /* Name */ const char *semanage_bool_get_name(const semanage_bool_t * boolean) { return sepol_bool_get_name(boolean); } hidden_def(semanage_bool_get_name) int semanage_bool_set_name(semanage_handle_t * handle, semanage_bool_t * boolean, const char *name) { int rc; char *subname = selinux_boolean_sub(name); rc = sepol_bool_set_name(handle->sepolh, boolean, subname); free(subname); return rc; } hidden_def(semanage_bool_set_name) /* Value */ int semanage_bool_get_value(const semanage_bool_t * boolean) { return sepol_bool_get_value(boolean); } hidden_def(semanage_bool_get_value) void semanage_bool_set_value(semanage_bool_t * boolean, int value) { sepol_bool_set_value(boolean, value); } hidden_def(semanage_bool_set_value) /* Create/Clone/Destroy */ int semanage_bool_create(semanage_handle_t * handle, semanage_bool_t ** bool_ptr) { return sepol_bool_create(handle->sepolh, bool_ptr); } hidden_def(semanage_bool_create) int semanage_bool_clone(semanage_handle_t * handle, const semanage_bool_t * boolean, semanage_bool_t ** bool_ptr) { return sepol_bool_clone(handle->sepolh, boolean, bool_ptr); } hidden_def(semanage_bool_clone) void semanage_bool_free(semanage_bool_t * boolean) { sepol_bool_free(boolean); } hidden_def(semanage_bool_free) /* Record base functions */ record_table_t SEMANAGE_BOOL_RTABLE = { .create = semanage_bool_create, .key_extract = semanage_bool_key_extract, .key_free = semanage_bool_key_free, .clone = semanage_bool_clone, .compare = semanage_bool_compare, .compare2 = semanage_bool_compare2, .compare2_qsort = semanage_bool_compare2_qsort, .free = semanage_bool_free, }; libsemanage-2.3/src/booleans_active.c000066400000000000000000000033371233221606300177210ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_bool; struct semanage_bool_key; typedef struct semanage_bool_key record_key_t; typedef struct semanage_bool record_t; #define DBASE_RECORD_DEFINED #include "boolean_internal.h" #include "handle.h" #include "database.h" int semanage_bool_set_active(semanage_handle_t * handle, const semanage_bool_key_t * key, const semanage_bool_t * data) { dbase_config_t *dconfig = semanage_bool_dbase_active(handle); return dbase_set(handle, dconfig, key, data); } int semanage_bool_query_active(semanage_handle_t * handle, const semanage_bool_key_t * key, semanage_bool_t ** response) { dbase_config_t *dconfig = semanage_bool_dbase_active(handle); return dbase_query(handle, dconfig, key, response); } int semanage_bool_exists_active(semanage_handle_t * handle, const semanage_bool_key_t * key, int *response) { dbase_config_t *dconfig = semanage_bool_dbase_active(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_bool_count_active(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_bool_dbase_active(handle); return dbase_count(handle, dconfig, response); } int semanage_bool_iterate_active(semanage_handle_t * handle, int (*handler) (const semanage_bool_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_bool_dbase_active(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_bool_list_active(semanage_handle_t * handle, semanage_bool_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_bool_dbase_active(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-2.3/src/booleans_activedb.c000066400000000000000000000071621233221606300202270ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_bool; struct semanage_bool_key; typedef struct semanage_bool record_t; typedef struct semanage_bool_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_activedb; typedef struct dbase_activedb dbase_t; #define DBASE_DEFINED #include #include #include #include #include "boolean_internal.h" #include "database_activedb.h" #include "parse_utils.h" #include "debug.h" static int bool_read_list(semanage_handle_t * handle, semanage_bool_t *** booleans, unsigned int *count) { semanage_bool_t **tmp_booleans = NULL; unsigned int tmp_count = 0; int i; char **names = NULL; int len = 0; /* Fetch boolean names */ if (security_get_boolean_names(&names, &len) < 0) { ERR(handle, "could not get list of boolean names"); goto err; } /* Allocate a sufficiently large array */ tmp_booleans = malloc(sizeof(semanage_bool_t *) * len); if (tmp_booleans == NULL) goto omem; /* Create records one by one */ for (i = 0; i < len; i++) { int value; if (semanage_bool_create(handle, &tmp_booleans[i]) < 0) goto err; tmp_count++; if (semanage_bool_set_name(handle, tmp_booleans[i], names[i]) < 0) goto err; value = security_get_boolean_active(names[i]); if (value < 0) { ERR(handle, "could not get the value " "for boolean %s", names[i]); goto err; } semanage_bool_set_value(tmp_booleans[i], value); } /* Success */ for (i = 0; i < len; i++) free(names[i]); free(names); *booleans = tmp_booleans; *count = tmp_count; return STATUS_SUCCESS; /* Failure */ omem: ERR(handle, "out of memory"); err: ERR(handle, "could not read boolean list"); for (i = 0; i < len; i++) free(names[i]); free(names); for (i = 0; (unsigned int)i < tmp_count; i++) semanage_bool_free(tmp_booleans[i]); free(tmp_booleans); return STATUS_ERR; } static int bool_commit_list(semanage_handle_t * handle, semanage_bool_t ** booleans, unsigned int count) { SELboolean *blist = NULL; const char *name; unsigned int bcount = 0; unsigned int i; int curvalue, newvalue; /* Allocate a sufficiently large array */ blist = malloc(sizeof(SELboolean) * count); if (blist == NULL) goto omem; /* Populate array */ for (i = 0; i < count; i++) { name = semanage_bool_get_name(booleans[i]); if (!name) goto omem; newvalue = semanage_bool_get_value(booleans[i]); curvalue = security_get_boolean_active(name); if (newvalue == curvalue) continue; blist[bcount].name = strdup(name); if (blist[bcount].name == NULL) goto omem; blist[bcount].value = newvalue; bcount++; } /* Commit */ if (security_set_boolean_list(bcount, blist, 0) < 0) { ERR(handle, "libselinux commit failed"); goto err; } for (i = 0; i < bcount; i++) free(blist[i].name); free(blist); return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: ERR(handle, "could not commit boolean list"); for (i = 0; i < bcount; i++) free(blist[i].name); free(blist); return STATUS_ERR; } /* BOOL RECORD: ACTIVEDB extension: method table */ record_activedb_table_t SEMANAGE_BOOL_ACTIVEDB_RTABLE = { .read_list = bool_read_list, .commit_list = bool_commit_list, }; int bool_activedb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig) { if (dbase_activedb_init(handle, &SEMANAGE_BOOL_RTABLE, &SEMANAGE_BOOL_ACTIVEDB_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_ACTIVEDB_DTABLE; return STATUS_SUCCESS; } void bool_activedb_dbase_release(dbase_config_t * dconfig) { dbase_activedb_release(dconfig->dbase); } libsemanage-2.3/src/booleans_file.c000066400000000000000000000055521233221606300173660ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_bool; struct semanage_bool_key; typedef struct semanage_bool record_t; typedef struct semanage_bool_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_file; typedef struct dbase_file dbase_t; #define DBASE_DEFINED #include #include #include #include #include #include "boolean_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" static int bool_print(semanage_handle_t * handle, semanage_bool_t * boolean, FILE * str) { const char *name = semanage_bool_get_name(boolean); int value = semanage_bool_get_value(boolean); if (fprintf(str, "%s=%d\n", name, value) < 0) { ERR(handle, "could not print boolean %s to stream", name); return STATUS_ERR; } return STATUS_SUCCESS; } static int bool_parse(semanage_handle_t * handle, parse_info_t * info, semanage_bool_t * boolean) { int value = 0; char *str = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (!info->ptr) goto last; /* Extract name */ if (parse_fetch_string(handle, info, &str, '=') < 0) goto err; if (semanage_bool_set_name(handle, boolean, str) < 0) goto err; free(str); str = NULL; /* Assert = */ if (parse_skip_space(handle, info) < 0) goto err; if (parse_assert_ch(handle, info, '=') < 0) goto err; /* Extract value */ if (parse_skip_space(handle, info) < 0) goto err; if (parse_optional_str(info, "true") != STATUS_NODATA) value = 1; else if (parse_optional_str(info, "TRUE") != STATUS_NODATA) value = 1; else if (parse_optional_str(info, "false") != STATUS_NODATA) value = 0; else if (parse_optional_str(info, "FALSE") != STATUS_NODATA) value = 0; else if (parse_fetch_int(handle, info, &value, ' ') < 0) goto err; if (value != 0 && value != 1) { ERR(handle, "invalid boolean value for \"%s\": %u " "(%s: %u)\n%s", semanage_bool_get_name(boolean), value, info->filename, info->lineno, info->orig_line); goto err; } semanage_bool_set_value(boolean, value); if (parse_assert_space(handle, info) < 0) goto err; return STATUS_SUCCESS; last: parse_dispose_line(info); return STATUS_NODATA; err: ERR(handle, "could not parse boolean record"); free(str); parse_dispose_line(info); return STATUS_ERR; } /* BOOL RECORD: FILE extension: method table */ record_file_table_t SEMANAGE_BOOL_FILE_RTABLE = { .parse = bool_parse, .print = bool_print, }; int bool_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig) { if (dbase_file_init(handle, fname, &SEMANAGE_BOOL_RTABLE, &SEMANAGE_BOOL_FILE_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_FILE_DTABLE; return STATUS_SUCCESS; } void bool_file_dbase_release(dbase_config_t * dconfig) { dbase_file_release(dconfig->dbase); } libsemanage-2.3/src/booleans_local.c000066400000000000000000000036521233221606300175400ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_bool; struct semanage_bool_key; typedef struct semanage_bool_key record_key_t; typedef struct semanage_bool record_t; #define DBASE_RECORD_DEFINED #include "boolean_internal.h" #include "handle.h" #include "database.h" int semanage_bool_modify_local(semanage_handle_t * handle, const semanage_bool_key_t * key, const semanage_bool_t * data) { dbase_config_t *dconfig = semanage_bool_dbase_local(handle); return dbase_modify(handle, dconfig, key, data); } int semanage_bool_del_local(semanage_handle_t * handle, const semanage_bool_key_t * key) { dbase_config_t *dconfig = semanage_bool_dbase_local(handle); return dbase_del(handle, dconfig, key); } int semanage_bool_query_local(semanage_handle_t * handle, const semanage_bool_key_t * key, semanage_bool_t ** response) { dbase_config_t *dconfig = semanage_bool_dbase_local(handle); return dbase_query(handle, dconfig, key, response); } int semanage_bool_exists_local(semanage_handle_t * handle, const semanage_bool_key_t * key, int *response) { dbase_config_t *dconfig = semanage_bool_dbase_local(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_bool_count_local(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_bool_dbase_local(handle); return dbase_count(handle, dconfig, response); } int semanage_bool_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_bool_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_bool_dbase_local(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_bool_list_local(semanage_handle_t * handle, semanage_bool_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_bool_dbase_local(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-2.3/src/booleans_policy.c000066400000000000000000000026501233221606300177420ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_bool; struct semanage_bool_key; typedef struct semanage_bool_key record_key_t; typedef struct semanage_bool record_t; #define DBASE_RECORD_DEFINED #include "boolean_internal.h" #include "handle.h" #include "database.h" int semanage_bool_query(semanage_handle_t * handle, const semanage_bool_key_t * key, semanage_bool_t ** response) { dbase_config_t *dconfig = semanage_bool_dbase_policy(handle); return dbase_query(handle, dconfig, key, response); } int semanage_bool_exists(semanage_handle_t * handle, const semanage_bool_key_t * key, int *response) { dbase_config_t *dconfig = semanage_bool_dbase_policy(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_bool_count(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_bool_dbase_policy(handle); return dbase_count(handle, dconfig, response); } int semanage_bool_iterate(semanage_handle_t * handle, int (*handler) (const semanage_bool_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_bool_dbase_policy(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_bool_list(semanage_handle_t * handle, semanage_bool_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_bool_dbase_policy(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-2.3/src/booleans_policydb.c000066400000000000000000000044011233221606300202440ustar00rootroot00000000000000/* * Copyright (C) 2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_bool; struct semanage_bool_key; typedef struct semanage_bool record_t; typedef struct semanage_bool_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_policydb; typedef struct dbase_policydb dbase_t; #define DBASE_DEFINED #include #include #include "boolean_internal.h" #include "debug.h" #include "database_policydb.h" /* BOOLEAN RECRORD (SEPOL): POLICYDB extension: method table */ record_policydb_table_t SEMANAGE_BOOL_POLICYDB_RTABLE = { .add = NULL, .modify = NULL, /* FIXME: these casts depend on stucts in libsepol matching structs * in libsemanage. This is incredibly fragile - the casting gets * rid of warnings, but is not type safe. */ .set = (record_policydb_table_set_t) sepol_bool_set, .query = (record_policydb_table_query_t) sepol_bool_query, .count = (record_policydb_table_count_t) sepol_bool_count, .exists = (record_policydb_table_exists_t) sepol_bool_exists, .iterate = (record_policydb_table_iterate_t) sepol_bool_iterate, }; int bool_policydb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig) { if (dbase_policydb_init(handle, "policy.kern", &SEMANAGE_BOOL_RTABLE, &SEMANAGE_BOOL_POLICYDB_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE; return STATUS_SUCCESS; } void bool_policydb_dbase_release(dbase_config_t * dconfig) { dbase_policydb_release(dconfig->dbase); } libsemanage-2.3/src/conf-parse.y000066400000000000000000000331451233221606300166470ustar00rootroot00000000000000/* Authors: Jason Tang * James Athey * * Copyright (C) 2004-2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ %{ #include "semanage_conf.h" #include "handle.h" #include #include #include #include #include #include #include extern int semanage_lex(); /* defined in conf-scan.c */ int semanage_error(char *msg); extern FILE *semanage_in; extern char *semanage_text; static int parse_module_store(char *arg); static void semanage_conf_external_prog_destroy(external_prog_t *ep); static int new_external_prog(external_prog_t **chain); static semanage_conf_t *current_conf; static external_prog_t *new_external; static int parse_errors; #define PASSIGN(p1,p2) { free(p1); p1 = p2; } %} %name-prefix="semanage_" %union { int d; char *s; } %token MODULE_STORE VERSION EXPAND_CHECK FILE_MODE SAVE_PREVIOUS SAVE_LINKED %token LOAD_POLICY_START SETFILES_START SEFCONTEXT_COMPILE_START DISABLE_GENHOMEDIRCON HANDLE_UNKNOWN USEPASSWD IGNOREDIRS %token BZIP_BLOCKSIZE BZIP_SMALL %token VERIFY_MOD_START VERIFY_LINKED_START VERIFY_KERNEL_START BLOCK_END %token PROG_PATH PROG_ARGS %token ARG %type verify_start_tok %% config_file: config_line config_file | /* empty */ ; config_line: single_opt | command_block | verify_block ; single_opt: module_store | version | expand_check | file_mode | save_previous | save_linked | disable_genhomedircon | usepasswd | ignoredirs | handle_unknown | bzip_blocksize | bzip_small ; module_store: MODULE_STORE '=' ARG { if (parse_module_store($3) != 0) { parse_errors++; YYABORT; } } ; version: VERSION '=' ARG { current_conf->policyvers = atoi($3); free($3); if (current_conf->policyvers < sepol_policy_kern_vers_min() || current_conf->policyvers > sepol_policy_kern_vers_max()) { parse_errors++; YYABORT; } } ; expand_check: EXPAND_CHECK '=' ARG { current_conf->expand_check = atoi($3); free($3); } ; file_mode: FILE_MODE '=' ARG { current_conf->file_mode = strtoul($3, NULL, 8); free($3); } ; save_previous: SAVE_PREVIOUS '=' ARG { if (strcasecmp($3, "true") == 0) current_conf->save_previous = 1; else if (strcasecmp($3, "false") == 0) current_conf->save_previous = 0; else { yyerror("save-previous can only be 'true' or 'false'"); } } ; save_linked: SAVE_LINKED '=' ARG { if (strcasecmp($3, "true") == 0) current_conf->save_linked = 1; else if (strcasecmp($3, "false") == 0) current_conf->save_linked = 0; else { yyerror("save-linked can only be 'true' or 'false'"); } } ; disable_genhomedircon: DISABLE_GENHOMEDIRCON '=' ARG { if (strcasecmp($3, "false") == 0) { current_conf->disable_genhomedircon = 0; } else if (strcasecmp($3, "true") == 0) { current_conf->disable_genhomedircon = 1; } else { yyerror("disable-genhomedircon can only be 'true' or 'false'"); } free($3); } usepasswd: USEPASSWD '=' ARG { if (strcasecmp($3, "false") == 0) { current_conf->usepasswd = 0; } else if (strcasecmp($3, "true") == 0) { current_conf->usepasswd = 1; } else { yyerror("usepasswd can only be 'true' or 'false'"); } free($3); } ignoredirs: IGNOREDIRS '=' ARG { current_conf->ignoredirs = strdup($3); } handle_unknown: HANDLE_UNKNOWN '=' ARG { if (strcasecmp($3, "deny") == 0) { current_conf->handle_unknown = SEPOL_DENY_UNKNOWN; } else if (strcasecmp($3, "reject") == 0) { current_conf->handle_unknown = SEPOL_REJECT_UNKNOWN; } else if (strcasecmp($3, "allow") == 0) { current_conf->handle_unknown = SEPOL_ALLOW_UNKNOWN; } else { yyerror("handle-unknown can only be 'deny', 'reject' or 'allow'"); } free($3); } bzip_blocksize: BZIP_BLOCKSIZE '=' ARG { int blocksize = atoi($3); free($3); if (blocksize > 9) yyerror("bzip-blocksize can only be in the range 0-9"); else current_conf->bzip_blocksize = blocksize; } bzip_small: BZIP_SMALL '=' ARG { if (strcasecmp($3, "false") == 0) { current_conf->bzip_small = 0; } else if (strcasecmp($3, "true") == 0) { current_conf->bzip_small = 1; } else { yyerror("bzip-small can only be 'true' or 'false'"); } free($3); } command_block: command_start external_opts BLOCK_END { if (new_external->path == NULL) { parse_errors++; YYABORT; } } ; command_start: LOAD_POLICY_START { semanage_conf_external_prog_destroy(current_conf->load_policy); current_conf->load_policy = NULL; if (new_external_prog(¤t_conf->load_policy) == -1) { parse_errors++; YYABORT; } } | SETFILES_START { semanage_conf_external_prog_destroy(current_conf->setfiles); current_conf->setfiles = NULL; if (new_external_prog(¤t_conf->setfiles) == -1) { parse_errors++; YYABORT; } } | SEFCONTEXT_COMPILE_START { semanage_conf_external_prog_destroy(current_conf->sefcontext_compile); current_conf->sefcontext_compile = NULL; if (new_external_prog(¤t_conf->sefcontext_compile) == -1) { parse_errors++; YYABORT; } } ; verify_block: verify_start external_opts BLOCK_END { if (new_external->path == NULL) { parse_errors++; YYABORT; } } ; verify_start: verify_start_tok { if ($1 == -1) { parse_errors++; YYABORT; } } ; verify_start_tok: VERIFY_MOD_START {$$ = new_external_prog(¤t_conf->mod_prog);} | VERIFY_LINKED_START {$$ = new_external_prog(¤t_conf->linked_prog);} | VERIFY_KERNEL_START {$$ = new_external_prog(¤t_conf->kernel_prog);} ; external_opts: external_opt external_opts | /* empty */ ; external_opt: PROG_PATH '=' ARG { PASSIGN(new_external->path, $3); } | PROG_ARGS '=' ARG { PASSIGN(new_external->args, $3); } ; %% static int semanage_conf_init(semanage_conf_t * conf) { conf->store_type = SEMANAGE_CON_DIRECT; conf->store_path = strdup(basename(semanage_policy_root())); conf->ignoredirs = NULL; conf->policyvers = sepol_policy_kern_vers_max(); conf->expand_check = 1; conf->handle_unknown = -1; conf->usepasswd = 1; conf->file_mode = 0644; conf->bzip_blocksize = 9; conf->bzip_small = 0; conf->save_previous = 0; conf->save_linked = 0; if ((conf->load_policy = calloc(1, sizeof(*(current_conf->load_policy)))) == NULL) { return -1; } if (access("/sbin/load_policy", X_OK) == 0) { conf->load_policy->path = strdup("/sbin/load_policy"); } else { conf->load_policy->path = strdup("/usr/sbin/load_policy"); } if (conf->load_policy->path == NULL) { return -1; } conf->load_policy->args = NULL; if ((conf->setfiles = calloc(1, sizeof(*(current_conf->setfiles)))) == NULL) { return -1; } if (access("/sbin/setfiles", X_OK) == 0) { conf->setfiles->path = strdup("/sbin/setfiles"); } else { conf->setfiles->path = strdup("/usr/sbin/setfiles"); } if ((conf->setfiles->path == NULL) || (conf->setfiles->args = strdup("-q -c $@ $<")) == NULL) { return -1; } if ((conf->sefcontext_compile = calloc(1, sizeof(*(current_conf->sefcontext_compile)))) == NULL) { return -1; } if (access("/sbin/sefcontext_compile", X_OK) == 0) { conf->sefcontext_compile->path = strdup("/sbin/sefcontext_compile"); } else { conf->sefcontext_compile->path = strdup("/usr/sbin/sefcontext_compile"); } if ((conf->sefcontext_compile->path == NULL) || (conf->sefcontext_compile->args = strdup("$@")) == NULL) { return -1; } return 0; } /* Parse a libsemanage configuration file. THIS FUNCTION IS NOT * THREAD-SAFE! Return a newly allocated semanage_conf_t *. If the * configuration file could be read, parse it; otherwise rely upon * default values. If the file could not be parsed correctly or if * out of memory return NULL. */ semanage_conf_t *semanage_conf_parse(const char *config_filename) { if ((current_conf = calloc(1, sizeof(*current_conf))) == NULL) { return NULL; } if (semanage_conf_init(current_conf) == -1) { goto cleanup; } if ((semanage_in = fopen(config_filename, "r")) == NULL) { /* configuration file does not exist or could not be * read. THIS IS NOT AN ERROR. just rely on the * defaults. */ return current_conf; } parse_errors = 0; semanage_parse(); fclose(semanage_in); if (parse_errors != 0) { goto cleanup; } return current_conf; cleanup: semanage_conf_destroy(current_conf); return NULL; } static void semanage_conf_external_prog_destroy(external_prog_t * ep) { while (ep != NULL) { external_prog_t *next = ep->next; free(ep->path); free(ep->args); free(ep); ep = next; } } /* Deallocates all space associated with a configuration struct, * including the pointer itself. */ void semanage_conf_destroy(semanage_conf_t * conf) { if (conf != NULL) { free(conf->store_path); free(conf->ignoredirs); semanage_conf_external_prog_destroy(conf->load_policy); semanage_conf_external_prog_destroy(conf->setfiles); semanage_conf_external_prog_destroy(conf->sefcontext_compile); semanage_conf_external_prog_destroy(conf->mod_prog); semanage_conf_external_prog_destroy(conf->linked_prog); semanage_conf_external_prog_destroy(conf->kernel_prog); free(conf); } } int semanage_error(char *msg) { fprintf(stderr, "error parsing semanage configuration file: %s\n", msg); parse_errors++; return 0; } /* Take the string argument for a module store. If it is exactly the * word "direct" then have libsemanage directly manipulate the module * store. The policy path will default to the active policy directory. * Otherwise if it begins with a forward slash interpret it as * an absolute path to a named socket, to which a policy server is * listening on the other end. Otherwise treat it as the host name to * an external server; if there is a colon in the name then everything * after gives a port number. The default port number is 4242. * Returns 0 on success, -1 if out of memory, -2 if a port number is * illegal. */ static int parse_module_store(char *arg) { /* arg is already a strdup()ed copy of yytext */ if (arg == NULL) { return -1; } free(current_conf->store_path); if (strcmp(arg, "direct") == 0) { current_conf->store_type = SEMANAGE_CON_DIRECT; current_conf->store_path = strdup(basename(semanage_policy_root())); current_conf->server_port = -1; free(arg); } else if (*arg == '/') { current_conf->store_type = SEMANAGE_CON_POLSERV_LOCAL; current_conf->store_path = arg; current_conf->server_port = -1; } else { char *s; current_conf->store_type = SEMANAGE_CON_POLSERV_REMOTE; if ((s = strchr(arg, ':')) == NULL) { current_conf->store_path = arg; current_conf->server_port = 4242; } else { char *endptr; *s = '\0'; current_conf->store_path = arg; current_conf->server_port = strtol(s + 1, &endptr, 10); if (*(s + 1) == '\0' || *endptr != '\0') { return -2; } } } return 0; } /* Helper function; called whenever configuration file specifies * another external program. Returns 0 on success, -1 if out of * memory. */ static int new_external_prog(external_prog_t ** chain) { if ((new_external = calloc(1, sizeof(*new_external))) == NULL) { return -1; } /* hook this new external program to the end of the chain */ if (*chain == NULL) { *chain = new_external; } else { external_prog_t *prog = *chain; while (prog->next != NULL) { prog = prog->next; } prog->next = new_external; } return 0; } libsemanage-2.3/src/conf-scan.l000066400000000000000000000057111233221606300164420ustar00rootroot00000000000000/* Authors: Jason Tang * James Athey * * Copyright (C) 2004-2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ %{ #include "conf-parse.h" #include #include static char *my_strdup (char * s); static char *my_qstrdup (char * s); int yywrap(void); %} %option stack prefix="semanage_" %option noinput nounput noyy_push_state noyy_pop_state noyy_top_state %x arg %% #.* /* ignore comments */ module-store return MODULE_STORE; policy-version return VERSION; expand-check return EXPAND_CHECK; file-mode return FILE_MODE; save-previous return SAVE_PREVIOUS; save-linked return SAVE_LINKED; disable-genhomedircon return DISABLE_GENHOMEDIRCON; usepasswd return USEPASSWD; ignoredirs return IGNOREDIRS; handle-unknown return HANDLE_UNKNOWN; bzip-blocksize return BZIP_BLOCKSIZE; bzip-small return BZIP_SMALL; "[load_policy]" return LOAD_POLICY_START; "[setfiles]" return SETFILES_START; "[sefcontext_compile]" return SEFCONTEXT_COMPILE_START; "[verify module]" return VERIFY_MOD_START; "[verify linked]" return VERIFY_LINKED_START; "[verify kernel]" return VERIFY_KERNEL_START; "[end]" return BLOCK_END; path return PROG_PATH; args return PROG_ARGS; [ \t]*=[ \t]* BEGIN arg; return '='; [ \t\n]+ /* ignore */ . return semanage_text[0]; \"\" BEGIN INITIAL; semanage_lval.s = NULL; return ARG; \".+\" BEGIN INITIAL; semanage_lval.s = my_qstrdup(semanage_text); return ARG; .*[^\"\n] BEGIN INITIAL; semanage_lval.s = my_strdup(semanage_text); return ARG; .|\n BEGIN INITIAL; semanage_lval.s = NULL; return ARG; %% int yywrap(void) { return 1; } /* Like strdup(), but also trim leading and trailing whitespace. * Returns NULL on error. */ static char *my_strdup(char *s) { char *t; while (isspace(*s)) { s++; } t = s + strlen(s) - 1; while (t >= s && isspace(*t)) { *t = '\0'; t--; } return strdup(s); } /* strdup() a string sans initial and trailing characters. Does /not/ * trim any whitespace. Returns NULL on error. */ static char *my_qstrdup(char *s) { s++; s[strlen(s) - 1] = '\0'; return strdup(s); } libsemanage-2.3/src/context_internal.h000066400000000000000000000004641233221606300201470ustar00rootroot00000000000000#ifndef _SEMANAGE_CONTEXT_INTERNAL_H_ #define _SEMANAGE_CONTEXT_INTERNAL_H_ #include #include "dso.h" hidden_proto(semanage_context_clone) hidden_proto(semanage_context_free) hidden_proto(semanage_context_from_string) hidden_proto(semanage_context_to_string) #endif libsemanage-2.3/src/context_record.c000066400000000000000000000045561233221606300176120ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #include #include "handle.h" typedef sepol_context_t semanage_context_t; #define _SEMANAGE_CONTEXT_DEFINED_ #include "context_internal.h" /* User */ const char *semanage_context_get_user(const semanage_context_t * con) { return sepol_context_get_user(con); } int semanage_context_set_user(semanage_handle_t * handle, semanage_context_t * con, const char *user) { return sepol_context_set_user(handle->sepolh, con, user); } /* Role */ const char *semanage_context_get_role(const semanage_context_t * con) { return sepol_context_get_role(con); } int semanage_context_set_role(semanage_handle_t * handle, semanage_context_t * con, const char *role) { return sepol_context_set_role(handle->sepolh, con, role); } /* Type */ const char *semanage_context_get_type(const semanage_context_t * con) { return sepol_context_get_type(con); } int semanage_context_set_type(semanage_handle_t * handle, semanage_context_t * con, const char *type) { return sepol_context_set_type(handle->sepolh, con, type); } /* MLS */ const char *semanage_context_get_mls(const semanage_context_t * con) { return sepol_context_get_mls(con); } int semanage_context_set_mls(semanage_handle_t * handle, semanage_context_t * con, const char *mls_range) { return sepol_context_set_mls(handle->sepolh, con, mls_range); } /* Create/Clone/Destroy */ int semanage_context_create(semanage_handle_t * handle, semanage_context_t ** con_ptr) { return sepol_context_create(handle->sepolh, con_ptr); } int semanage_context_clone(semanage_handle_t * handle, const semanage_context_t * con, semanage_context_t ** con_ptr) { return sepol_context_clone(handle->sepolh, con, con_ptr); } hidden_def(semanage_context_clone) void semanage_context_free(semanage_context_t * con) { sepol_context_free(con); } hidden_def(semanage_context_free) /* Parse to/from string */ int semanage_context_from_string(semanage_handle_t * handle, const char *str, semanage_context_t ** con) { return sepol_context_from_string(handle->sepolh, str, con); } hidden_def(semanage_context_from_string) int semanage_context_to_string(semanage_handle_t * handle, const semanage_context_t * con, char **str_ptr) { return sepol_context_to_string(handle->sepolh, con, str_ptr); } hidden_def(semanage_context_to_string) libsemanage-2.3/src/database.c000066400000000000000000000101621233221606300163220ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #include #include "semanage_store.h" #include "semanage_conf.h" #include "database.h" #include "debug.h" static int assert_init(semanage_handle_t * handle, dbase_config_t * dconfig) { if (dconfig->dtable == NULL) { ERR(handle, "A direct or server connection is needed " "to use this function - please call " "the corresponding connect() method"); return STATUS_ERR; } return STATUS_SUCCESS; } static int enter_ro(semanage_handle_t * handle, dbase_config_t * dconfig) { if (assert_init(handle, dconfig) < 0) goto err; if (!handle->is_in_transaction && handle->conf->store_type == SEMANAGE_CON_DIRECT) { if (semanage_get_active_lock(handle) < 0) { ERR(handle, "could not get the active lock"); goto err; } } if (dconfig->dtable->cache(handle, dconfig->dbase) < 0) goto err; return STATUS_SUCCESS; err: ERR(handle, "could not enter read-only section"); return STATUS_ERR; } static inline int exit_ro(semanage_handle_t * handle) { int commit_num = handle->funcs->get_serial(handle); if (!handle->is_in_transaction && handle->conf->store_type == SEMANAGE_CON_DIRECT) semanage_release_active_lock(handle); return commit_num; } static int enter_rw(semanage_handle_t * handle, dbase_config_t * dconfig) { if (assert_init(handle, dconfig) < 0) goto err; if (!handle->is_in_transaction) { ERR(handle, "this operation requires a transaction"); goto err; } if (dconfig->dtable->cache(handle, dconfig->dbase) < 0) goto err; return STATUS_SUCCESS; err: ERR(handle, "could not enter read-write section"); return STATUS_ERR; } int dbase_modify(semanage_handle_t * handle, dbase_config_t * dconfig, const record_key_t * key, const record_t * data) { if (enter_rw(handle, dconfig) < 0) return STATUS_ERR; if (dconfig->dtable->modify(handle, dconfig->dbase, key, data) < 0) return STATUS_ERR; return STATUS_SUCCESS; } int dbase_set(semanage_handle_t * handle, dbase_config_t * dconfig, const record_key_t * key, const record_t * data) { if (enter_rw(handle, dconfig) < 0) return STATUS_ERR; if (dconfig->dtable->set(handle, dconfig->dbase, key, data) < 0) return STATUS_ERR; return STATUS_SUCCESS; } int dbase_del(semanage_handle_t * handle, dbase_config_t * dconfig, const record_key_t * key) { if (enter_rw(handle, dconfig) < 0) return STATUS_ERR; if (dconfig->dtable->del(handle, dconfig->dbase, key) < 0) return STATUS_ERR; return STATUS_SUCCESS; } int dbase_query(semanage_handle_t * handle, dbase_config_t * dconfig, const record_key_t * key, record_t ** response) { if (enter_ro(handle, dconfig) < 0) return STATUS_ERR; if (dconfig->dtable->query(handle, dconfig->dbase, key, response) < 0) { exit_ro(handle); return STATUS_ERR; } return exit_ro(handle); } int dbase_exists(semanage_handle_t * handle, dbase_config_t * dconfig, const record_key_t * key, int *response) { if (enter_ro(handle, dconfig) < 0) return STATUS_ERR; if (dconfig->dtable->exists(handle, dconfig->dbase, key, response) < 0) { exit_ro(handle); return STATUS_ERR; } return exit_ro(handle); } int dbase_count(semanage_handle_t * handle, dbase_config_t * dconfig, unsigned int *response) { if (enter_ro(handle, dconfig) < 0) return STATUS_ERR; if (dconfig->dtable->count(handle, dconfig->dbase, response) < 0) { exit_ro(handle); return STATUS_ERR; } return exit_ro(handle); } int dbase_iterate(semanage_handle_t * handle, dbase_config_t * dconfig, int (*fn) (const record_t * record, void *fn_arg), void *fn_arg) { if (enter_ro(handle, dconfig) < 0) return STATUS_ERR; if (dconfig->dtable->iterate(handle, dconfig->dbase, fn, fn_arg) < 0) { exit_ro(handle); return STATUS_ERR; } return exit_ro(handle); } int dbase_list(semanage_handle_t * handle, dbase_config_t * dconfig, record_t *** records, unsigned int *count) { if (enter_ro(handle, dconfig) < 0) return STATUS_ERR; if (dconfig->dtable->list(handle, dconfig->dbase, records, count) < 0) { exit_ro(handle); return STATUS_ERR; } return exit_ro(handle); } libsemanage-2.3/src/database.h000066400000000000000000000153361233221606300163370ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_DATABASE_H_ #define _SEMANAGE_DATABASE_H_ #ifndef DBASE_RECORD_DEFINED typedef void *record_t; typedef void *record_key_t; #define DBASE_RECORD_DEFINED #endif #ifndef DBASE_DEFINED typedef void *dbase_t; #define DBASE_DEFINED #endif /* Circular dependency */ struct semanage_handle; /* RECORD interface - method table */ typedef struct record_table { /* Create a record */ int (*create) (struct semanage_handle * handle, record_t ** rec); /* Extract key from record */ int (*key_extract) (struct semanage_handle * handle, const record_t * rec, record_key_t ** key); /* Free record key */ void (*key_free) (record_key_t * key); /* Return 0 if the record matches the key, * -1 if the key represents a record that should * be ordered before this record, and 1 if vice-versa */ int (*compare) (const record_t * rec, const record_key_t * key); /* Return 0 if the record matches record2, * -1 if record2 should be ordered before this record, * and 1 if vice-versa */ int (*compare2) (const record_t * rec, const record_t * rec2); /* Same as above, but dereferences the pointer first. * This function is intenteded to be used as a qsort * comparator. */ int (*compare2_qsort) (const record_t ** rec, const record_t ** rec2); /* Deep-copy clone of this record */ int (*clone) (struct semanage_handle * handle, const record_t * rec, record_t ** new_rec); /* Deallocate record resources. Must sucessfully handle NULL. */ void (*free) (record_t * rec); } record_table_t; /* DBASE interface - method table */ typedef struct dbase_table { /* --------------- Database Functionality ----------- */ /* Note: In all the functions below, the key is property * of the caller, and will not be modified by the database. * In add/set/modify, the data is also property of the caller */ /* Add the specified record to * the database. No check for duplicates is performed */ int (*add) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key, const record_t * data); /* Add the specified record to the * database if it not present. * If it's present, replace it */ int (*modify) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key, const record_t * data); /* Modify the specified record in the database * if it is present. Fail if it does not yet exist */ int (*set) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key, const record_t * data); /* Delete a record */ int (*del) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key); /* Clear all records, and leave the database in * cached, modified state. This function does * not require a call to cache() */ int (*clear) (struct semanage_handle * handle, dbase_t * dbase); /* Retrieve a record * * Note: the resultant record * becomes property of the caller, and * must be freed accordingly */ int (*query) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key, record_t ** response); /* Check if a record exists */ int (*exists) (struct semanage_handle * handle, dbase_t * dbase, const record_key_t * key, int *response); /* Count the number of records */ int (*count) (struct semanage_handle * handle, dbase_t * dbase, unsigned int *response); /* Execute the specified handler over * the records of this database. The handler * can signal a successful exit by returning 1, * an error exit by returning -1, and continue by * returning 0 * * Note: The record passed into the iterate handler * may or may not persist after the handler invocation, * and writing to it has unspecified behavior. It *must* * be cloned if modified, or preserved. * * Note: The iterate handler may not invoke any other * semanage read functions outside a transaction. It is only * reentrant while in transaction. The iterate handler may * not modify the underlying database. */ int (*iterate) (struct semanage_handle * handle, dbase_t * dbase, int (*fn) (const record_t * record, void *varg), void *fn_arg); /* Construct a list of all records in this database * * Note: The list returned becomes property of the caller, * and must be freed accordingly. */ int (*list) (struct semanage_handle * handle, dbase_t * dbase, record_t *** records, unsigned int *count); /* ---------- Cache/Transaction Management ---------- */ /* Cache the database (if supported). * This function must be invoked before using * any of the database functions above. It may be invoked * multiple times, and will update the cache if a commit * occured between invocations */ int (*cache) (struct semanage_handle * handle, dbase_t * dbase); /* Forgets all changes that haven't been written * to the database backend */ void (*drop_cache) (dbase_t * dbase); /* Checks if there are any changes not written to the backend */ int (*is_modified) (dbase_t * dbase); /* Writes the database changes to its backend */ int (*flush) (struct semanage_handle * handle, dbase_t * dbase); /* ------------- Polymorphism ----------------------- */ /* Retrieves the record table for this database, * which specifies how to perform basic operations * on each record. */ record_table_t *(*get_rtable) (dbase_t * dbase); } dbase_table_t; typedef struct dbase_config { /* Database state */ dbase_t *dbase; /* Database methods */ dbase_table_t *dtable; } dbase_config_t; extern int dbase_add(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key, const record_t * data); extern int dbase_modify(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key, const record_t * data); extern int dbase_set(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key, const record_t * data); extern int dbase_del(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key); extern int dbase_query(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key, record_t ** response); extern int dbase_exists(struct semanage_handle *handle, dbase_config_t * dconfig, const record_key_t * key, int *response); extern int dbase_count(struct semanage_handle *handle, dbase_config_t * dconfig, unsigned int *response); extern int dbase_iterate(struct semanage_handle *handle, dbase_config_t * dconfig, int (*fn) (const record_t * record, void *fn_arg), void *fn_arg); extern int dbase_list(struct semanage_handle *handle, dbase_config_t * dconfig, record_t *** records, unsigned int *count); #endif libsemanage-2.3/src/database_activedb.c000066400000000000000000000076671233221606300202030ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: dbase_activedb_t (Active/Kernel) * Extends: dbase_llist_t (Linked List) * Implements: dbase_t (Database) */ struct dbase_activedb; typedef struct dbase_activedb dbase_t; #define DBASE_DEFINED #include #include #include #include "debug.h" #include "handle.h" #include "database_activedb.h" #include "database_llist.h" /* ACTIVEDB dbase */ struct dbase_activedb { /* Parent object - must always be * the first field - here we are using * a linked list to store the records */ dbase_llist_t llist; /* ACTIVEDB extension */ record_activedb_table_t *ratable; }; static int dbase_activedb_cache(semanage_handle_t * handle, dbase_activedb_t * dbase) { record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist); record_activedb_table_t *ratable = dbase->ratable; record_t **records = NULL; unsigned int rcount = 0; unsigned int i = 0; /* Already cached */ if (!dbase_llist_needs_resync(handle, &dbase->llist)) return STATUS_SUCCESS; /* Update cache serial */ dbase_llist_cache_init(&dbase->llist); if (dbase_llist_set_serial(handle, &dbase->llist) < 0) goto err; /* Fetch the entire list */ if (ratable->read_list(handle, &records, &rcount) < 0) goto err; /* Add records one by one */ for (; i < rcount; i++) { if (dbase_llist_cache_prepend(handle, &dbase->llist, records[i]) < 0) goto err; rtable->free(records[i]); } free(records); return STATUS_SUCCESS; err: ERR(handle, "could not cache active database"); for (; i < rcount; i++) rtable->free(records[i]); dbase_llist_drop_cache(&dbase->llist); free(records); return STATUS_ERR; } static int dbase_activedb_flush(semanage_handle_t * handle, dbase_activedb_t * dbase) { record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist); record_activedb_table_t *ratable = dbase->ratable; record_t **records = NULL; unsigned int rcount = 0; unsigned int i; /* Not cached, or not modified - flush is not necessary */ if (!dbase_llist_is_modified(&dbase->llist)) return STATUS_SUCCESS; /* Fetch list */ if (dbase_llist_list(handle, &dbase->llist, &records, &rcount) < 0) goto err; /* Commit */ if (ratable->commit_list(handle, records, rcount) < 0) goto err; for (i = 0; i < rcount; i++) rtable->free(records[i]); free(records); dbase_llist_set_modified(&dbase->llist, 0); return STATUS_SUCCESS; err: for (i = 0; i < rcount; i++) rtable->free(records[i]); free(records); ERR(handle, "could not flush active database"); return STATUS_ERR; } int dbase_activedb_init(semanage_handle_t * handle, record_table_t * rtable, record_activedb_table_t * ratable, dbase_activedb_t ** dbase) { dbase_activedb_t *tmp_dbase = (dbase_activedb_t *) malloc(sizeof(dbase_activedb_t)); if (!tmp_dbase) goto omem; tmp_dbase->ratable = ratable; dbase_llist_init(&tmp_dbase->llist, rtable, &SEMANAGE_ACTIVEDB_DTABLE); *dbase = tmp_dbase; return STATUS_SUCCESS; omem: ERR(handle, "out of memory, could not initialize active database"); free(tmp_dbase); return STATUS_ERR; } /* Release dbase resources */ void dbase_activedb_release(dbase_activedb_t * dbase) { dbase_llist_drop_cache(&dbase->llist); free(dbase); } /* ACTIVEDB dbase - method table implementation */ dbase_table_t SEMANAGE_ACTIVEDB_DTABLE = { /* Cache/Transactions */ .cache = dbase_activedb_cache, .drop_cache = (void *)dbase_llist_drop_cache, .flush = dbase_activedb_flush, .is_modified = (void *)dbase_llist_is_modified, /* Database API */ .iterate = (void *)dbase_llist_iterate, .exists = (void *)dbase_llist_exists, .list = (void *)dbase_llist_list, .add = (void *)dbase_llist_add, .set = (void *)dbase_llist_set, .del = (void *)dbase_llist_del, .clear = (void *)dbase_llist_clear, .modify = (void *)dbase_llist_modify, .query = (void *)dbase_llist_query, .count = (void *)dbase_llist_count, /* Polymorphism */ .get_rtable = (void *)dbase_llist_get_rtable }; libsemanage-2.3/src/database_activedb.h000066400000000000000000000020141233221606300201650ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_DATABASE_ACTIVEDB_INTERNAL_H_ #define _SEMANAGE_DATABASE_ACTIVEDB_INTERNAL_H_ #include "database.h" #include "handle.h" struct dbase_activedb; typedef struct dbase_activedb dbase_activedb_t; /* ACTIVEDB extension to RECORD interface - method table */ typedef struct record_activedb_table { /* Read a list of records */ int (*read_list) (semanage_handle_t * handle, record_t *** records, unsigned int *count); /* Commit a list of records */ int (*commit_list) (semanage_handle_t * handle, record_t ** records, unsigned int count); } record_activedb_table_t; /* ACTIVEDB - initialization */ extern int dbase_activedb_init(semanage_handle_t * handle, record_table_t * rtable, record_activedb_table_t * ratable, dbase_activedb_t ** dbase); /* ACTIVEDB - release */ extern void dbase_activedb_release(dbase_activedb_t * dbase); /* ACTIVEDB - method table implementation */ extern dbase_table_t SEMANAGE_ACTIVEDB_DTABLE; #endif libsemanage-2.3/src/database_file.c000066400000000000000000000126531233221606300173300ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: dbase_file_t (File) * Extends: dbase_llist_t (Linked List) * Implements: dbase_t (Database) */ struct dbase_file; typedef struct dbase_file dbase_t; #define DBASE_DEFINED #include #include #include #include #include #include #include "debug.h" #include "handle.h" #include "parse_utils.h" #include "database_file.h" #include "database_llist.h" #include "semanage_store.h" /* FILE dbase */ struct dbase_file { /* Parent object - must always be * the first field - here we are using * a linked list to store the records */ dbase_llist_t llist; /* Backing file suffix */ const char *suffix; /* FILE extension */ record_file_table_t *rftable; }; static int construct_filename(semanage_handle_t * handle, dbase_file_t * dbase, char **filename) { const char *path = (handle->is_in_transaction) ? semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL) : semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL); size_t fname_length = strlen(path) + strlen(dbase->suffix) + 2; char *fname = malloc(fname_length); if (!fname) { ERR(handle, "out of memory, could not construct filename"); return STATUS_ERR; } snprintf(fname, fname_length, "%s/%s", path, dbase->suffix); *filename = fname; return STATUS_SUCCESS; } static int dbase_file_cache(semanage_handle_t * handle, dbase_file_t * dbase) { record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist); record_file_table_t *rftable = dbase->rftable; record_t *process_record = NULL; int pstatus = STATUS_SUCCESS; parse_info_t *parse_info = NULL; char *fname = NULL; /* Already cached */ if (!dbase_llist_needs_resync(handle, &dbase->llist)) return STATUS_SUCCESS; /* Update cache serial */ dbase_llist_cache_init(&dbase->llist); if (dbase_llist_set_serial(handle, &dbase->llist) < 0) goto err; if (construct_filename(handle, dbase, &fname) < 0) goto err; if (parse_init(handle, fname, NULL, &parse_info) < 0) goto err; if (parse_open(handle, parse_info) < 0) goto err; /* Main processing loop */ do { /* Create record */ if (rtable->create(handle, &process_record) < 0) goto err; /* Parse record */ pstatus = rftable->parse(handle, parse_info, process_record); /* Parse error */ if (pstatus < 0) goto err; /* End of file */ else if (pstatus == STATUS_NODATA) break; /* Prepend to cache */ if (dbase_llist_cache_prepend(handle, &dbase->llist, process_record) < 0) goto err; rtable->free(process_record); process_record = NULL; } while (pstatus != STATUS_NODATA); rtable->free(process_record); parse_close(parse_info); parse_release(parse_info); free(fname); return STATUS_SUCCESS; err: ERR(handle, "could not cache file database"); rtable->free(process_record); if (parse_info) { parse_close(parse_info); parse_release(parse_info); } dbase_llist_drop_cache(&dbase->llist); free(fname); return STATUS_ERR; } /* Flush database to file */ static int dbase_file_flush(semanage_handle_t * handle, dbase_file_t * dbase) { record_file_table_t *rftable = dbase->rftable; cache_entry_t *ptr; char *fname = NULL; FILE *str = NULL; if (!dbase_llist_is_modified(&dbase->llist)) return STATUS_SUCCESS; if (construct_filename(handle, dbase, &fname) < 0) goto err; str = fopen(fname, "w"); if (!str) { ERR(handle, "could not open %s for writing: %s", fname, strerror(errno)); goto err; } __fsetlocking(str, FSETLOCKING_BYCALLER); if (fprintf(str, "# This file is auto-generated by libsemanage\n" "# Do not edit directly.\n\n") < 0) { ERR(handle, "could not write file header for %s", fname); goto err; } for (ptr = dbase->llist.cache_tail; ptr != NULL; ptr = ptr->prev) { if (rftable->print(handle, ptr->data, str) < 0) goto err; } dbase_llist_set_modified(&dbase->llist, 0); fclose(str); free(fname); return STATUS_SUCCESS; err: if (str != NULL) fclose(str); ERR(handle, "could not flush database to file"); free(fname); return STATUS_ERR; } int dbase_file_init(semanage_handle_t * handle, const char *suffix, record_table_t * rtable, record_file_table_t * rftable, dbase_file_t ** dbase) { dbase_file_t *tmp_dbase = (dbase_file_t *) malloc(sizeof(dbase_file_t)); if (!tmp_dbase) goto omem; tmp_dbase->suffix = suffix; tmp_dbase->rftable = rftable; dbase_llist_init(&tmp_dbase->llist, rtable, &SEMANAGE_FILE_DTABLE); *dbase = tmp_dbase; return STATUS_SUCCESS; omem: ERR(handle, "out of memory, could not initialize file database"); free(tmp_dbase); return STATUS_ERR; } /* Release dbase resources */ void dbase_file_release(dbase_file_t * dbase) { dbase_llist_drop_cache(&dbase->llist); free(dbase); } /* FILE dbase - method table implementation */ dbase_table_t SEMANAGE_FILE_DTABLE = { /* Cache/Transactions */ .cache = dbase_file_cache, .drop_cache = (void *)dbase_llist_drop_cache, .flush = dbase_file_flush, .is_modified = (void *)dbase_llist_is_modified, /* Database API */ .iterate = (void *)dbase_llist_iterate, .exists = (void *)dbase_llist_exists, .list = (void *)dbase_llist_list, .add = (void *)dbase_llist_add, .set = (void *)dbase_llist_set, .del = (void *)dbase_llist_del, .clear = (void *)dbase_llist_clear, .modify = (void *)dbase_llist_modify, .query = (void *)dbase_llist_query, .count = (void *)dbase_llist_count, /* Polymorphism */ .get_rtable = (void *)dbase_llist_get_rtable }; libsemanage-2.3/src/database_file.h000066400000000000000000000021731233221606300173310ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_DATABASE_FILE_INTERNAL_H_ #define _SEMANAGE_DATABASE_FILE_INTERNAL_H_ #include #include "database.h" #include "parse_utils.h" #include "handle.h" struct dbase_file; typedef struct dbase_file dbase_file_t; /* FILE extension to RECORD interface - method table */ typedef struct record_file_table { /* Fill record structuure based on supplied parse info. * Parser must return STATUS_NODATA when EOF is encountered. * Parser must handle NULL file stream correctly */ int (*parse) (semanage_handle_t * handle, parse_info_t * info, record_t * record); /* Print record to stream */ int (*print) (semanage_handle_t * handle, record_t * record, FILE * str); } record_file_table_t; /* FILE - initialization */ extern int dbase_file_init(semanage_handle_t * handle, const char *suffix, record_table_t * rtable, record_file_table_t * rftable, dbase_file_t ** dbase); /* FILE - release */ extern void dbase_file_release(dbase_file_t * dbase); /* FILE - method table implementation */ extern dbase_table_t SEMANAGE_FILE_DTABLE; #endif libsemanage-2.3/src/database_join.c000066400000000000000000000164701233221606300173510ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: dbase_join_t (Join) * Extends: dbase_llist_t (Linked List) * Implements: dbase_t (Database) */ struct dbase_join; typedef struct dbase_join dbase_t; #define DBASE_DEFINED #include #include "user_internal.h" #include "debug.h" #include "handle.h" #include "database_join.h" #include "database_llist.h" /* JOIN dbase */ struct dbase_join { /* Parent object - must always be * the first field - here we are using * a linked list to store the records */ dbase_llist_t llist; /* Backing databases - for each * thing being joined */ dbase_config_t *join1; dbase_config_t *join2; /* JOIN extension */ record_join_table_t *rjtable; }; static int dbase_join_cache(semanage_handle_t * handle, dbase_join_t * dbase) { /* Extract all the object tables information */ dbase_t *dbase1 = dbase->join1->dbase; dbase_t *dbase2 = dbase->join2->dbase; dbase_table_t *dtable1 = dbase->join1->dtable; dbase_table_t *dtable2 = dbase->join2->dtable; record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist); record_join_table_t *rjtable = dbase->rjtable; record_table_t *rtable1 = dtable1->get_rtable(dbase1); record_table_t *rtable2 = dtable2->get_rtable(dbase2); record_key_t *rkey = NULL; record_t *record = NULL; record1_t **records1 = NULL; record2_t **records2 = NULL; unsigned int rcount1 = 0, rcount2 = 0, i = 0, j = 0; /* Already cached */ if (!dbase_llist_needs_resync(handle, &dbase->llist)) return STATUS_SUCCESS; /* Update cache serial */ dbase_llist_cache_init(&dbase->llist); if (dbase_llist_set_serial(handle, &dbase->llist) < 0) goto err; /* First cache any child dbase, which must * be the first thing done when calling dbase * functions internally */ if (dtable1->cache(handle, dbase1) < 0) goto err; if (dtable2->cache(handle, dbase2) < 0) goto err; /* Fetch records */ if (dtable1->list(handle, dbase1, &records1, &rcount1) < 0) goto err; if (dtable2->list(handle, dbase2, &records2, &rcount2) < 0) goto err; /* Sort for quicker merge later */ qsort(records1, rcount1, sizeof(record1_t *), (int (*)(const void *, const void *))rtable1->compare2_qsort); qsort(records2, rcount2, sizeof(record2_t *), (int (*)(const void *, const void *))rtable2->compare2_qsort); /* Now merge into this dbase */ while (i < rcount1 || j < rcount2) { int rc; /* End of one list, or the other */ if (i == rcount1) rc = -1; else if (j == rcount2) rc = 1; /* Still more records to go, compare them */ else { if (rtable1->key_extract(handle, records1[i], &rkey) < 0) goto err; rc = rtable2->compare(records2[j], rkey); rtable->key_free(rkey); rkey = NULL; } /* Missing record1 data */ if (rc < 0) { if (rjtable->join(handle, NULL, records2[j], &record) < 0) goto err; j++; } /* Missing record2 data */ else if (rc > 0) { if (rjtable->join(handle, records1[i], NULL, &record) < 0) goto err; i++; } /* Both records available */ else { if (rjtable->join(handle, records1[i], records2[j], &record) < 0) goto err; i++; j++; } /* Add result record to database */ if (dbase_llist_cache_prepend(handle, &dbase->llist, record) < 0) goto err; rtable->free(record); record = NULL; } /* Update cache serial */ if (dbase_llist_set_serial(handle, &dbase->llist) < 0) goto err; for (i = 0; i < rcount1; i++) rtable1->free(records1[i]); for (i = 0; i < rcount2; i++) rtable2->free(records2[i]); free(records1); free(records2); return STATUS_SUCCESS; err: ERR(handle, "could not cache join database"); for (i = 0; i < rcount1; i++) rtable1->free(records1[i]); for (i = 0; i < rcount2; i++) rtable2->free(records2[i]); free(records1); free(records2); rtable->key_free(rkey); rtable->free(record); dbase_llist_drop_cache(&dbase->llist); return STATUS_ERR; } /* Flush database */ static int dbase_join_flush(semanage_handle_t * handle, dbase_join_t * dbase) { /* Extract all the object tables information */ dbase_t *dbase1 = dbase->join1->dbase; dbase_t *dbase2 = dbase->join2->dbase; dbase_table_t *dtable1 = dbase->join1->dtable; dbase_table_t *dtable2 = dbase->join2->dtable; record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist); record_join_table_t *rjtable = dbase->rjtable; record_table_t *rtable1 = dtable1->get_rtable(dbase1); record_table_t *rtable2 = dtable2->get_rtable(dbase2); cache_entry_t *ptr; record_key_t *rkey = NULL; record1_t *record1 = NULL; record2_t *record2 = NULL; /* No effect of flush */ if (!dbase_llist_is_modified(&dbase->llist)) return STATUS_SUCCESS; /* Then clear all records from the cache. * This is *not* the same as dropping the cache - it's an explicit * request to delete all current records. We need to do * this because we don't store delete deltas for the join, * so we must re-add all records from scratch */ if (dtable1->clear(handle, dbase1) < 0) goto err; if (dtable2->clear(handle, dbase2) < 0) goto err; /* For each record, split, and add parts into their corresponding databases */ for (ptr = dbase->llist.cache_tail; ptr != NULL; ptr = ptr->prev) { if (rtable->key_extract(handle, ptr->data, &rkey) < 0) goto err; if (rjtable->split(handle, ptr->data, &record1, &record2) < 0) goto err; if (dtable1->add(handle, dbase1, rkey, record1) < 0) goto err; if (dtable2->add(handle, dbase2, rkey, record2) < 0) goto err; rtable->key_free(rkey); rtable1->free(record1); rtable2->free(record2); rkey = NULL; record1 = NULL; record2 = NULL; } /* Note that this function does not flush the child databases, it * leaves that decision up to higher-level code */ dbase_llist_set_modified(&dbase->llist, 0); return STATUS_SUCCESS; err: ERR(handle, "could not flush join database"); rtable->key_free(rkey); rtable1->free(record1); rtable2->free(record2); return STATUS_ERR; } int dbase_join_init(semanage_handle_t * handle, record_table_t * rtable, record_join_table_t * rjtable, dbase_config_t * join1, dbase_config_t * join2, dbase_t ** dbase) { dbase_join_t *tmp_dbase = malloc(sizeof(dbase_join_t)); if (!tmp_dbase) goto omem; dbase_llist_init(&tmp_dbase->llist, rtable, &SEMANAGE_JOIN_DTABLE); tmp_dbase->rjtable = rjtable; tmp_dbase->join1 = join1; tmp_dbase->join2 = join2; *dbase = tmp_dbase; return STATUS_SUCCESS; omem: ERR(handle, "out of memory, could not initialize join database"); free(tmp_dbase); return STATUS_ERR; } /* Release dbase resources */ void dbase_join_release(dbase_join_t * dbase) { dbase_llist_drop_cache(&dbase->llist); free(dbase); } /* JOIN dbase - method table implementation */ dbase_table_t SEMANAGE_JOIN_DTABLE = { /* Cache/Transactions */ .cache = dbase_join_cache, .drop_cache = (void *)dbase_llist_drop_cache, .flush = dbase_join_flush, .is_modified = (void *)dbase_llist_is_modified, /* Database API */ .iterate = (void *)dbase_llist_iterate, .exists = (void *)dbase_llist_exists, .list = (void *)dbase_llist_list, .add = (void *)dbase_llist_add, .set = (void *)dbase_llist_set, .del = (void *)dbase_llist_del, .clear = (void *)dbase_llist_clear, .modify = (void *)dbase_llist_modify, .query = (void *)dbase_llist_query, .count = (void *)dbase_llist_count, /* Polymorphism */ .get_rtable = (void *)dbase_llist_get_rtable }; libsemanage-2.3/src/database_join.h000066400000000000000000000023421233221606300173470ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_DATABASE_JOIN_INTERNAL_H_ #define _SEMANAGE_DATABASE_JOIN_INTERNAL_H_ #include "database.h" #include "handle.h" #ifndef DBASE_RECORD_JOIN_DEFINED typedef void *record1_t; typedef void *record2_t; #define DBASE_RECORD_JOIN_DEFINED #endif struct dbase_join; typedef struct dbase_join dbase_join_t; /* JOIN extension to RECORD interface - method table */ typedef struct record_join_table { /* Join two records together. * One of the provided records could be NULL */ int (*join) (semanage_handle_t * handle, const record1_t * record1, const record2_t * record2, record_t ** result); /* Splits a record into two */ int (*split) (semanage_handle_t * handle, const record_t * record, record1_t ** split1, record2_t ** split2); } record_join_table_t; /* JOIN - initialization */ extern int dbase_join_init(semanage_handle_t * handle, record_table_t * rtable, record_join_table_t * rjtable, dbase_config_t * join1, dbase_config_t * join2, dbase_join_t ** dbase); /* FILE - release */ extern void dbase_join_release(dbase_join_t * dbase); /* JOIN - method table implementation */ extern dbase_table_t SEMANAGE_JOIN_DTABLE; #endif libsemanage-2.3/src/database_llist.c000066400000000000000000000172321233221606300175360ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: dbase_llist_t (Linked List) * Partially Implements: dbase_t (Database) */ struct dbase_llist; typedef struct dbase_llist dbase_t; #define DBASE_DEFINED #include #include "debug.h" #include "handle.h" #include "database_llist.h" int dbase_llist_needs_resync(semanage_handle_t * handle, dbase_llist_t * dbase) { int cache_serial; if (dbase->cache_serial < 0) return 1; cache_serial = handle->funcs->get_serial(handle); if (cache_serial < 0) return 1; if (cache_serial != dbase->cache_serial) { dbase_llist_drop_cache(dbase); dbase->cache_serial = -1; return 1; } return 0; } /* Helper for adding records to the cache */ int dbase_llist_cache_prepend(semanage_handle_t * handle, dbase_llist_t * dbase, const record_t * data) { /* Initialize */ cache_entry_t *entry = (cache_entry_t *) malloc(sizeof(cache_entry_t)); if (entry == NULL) goto omem; if (dbase->rtable->clone(handle, data, &entry->data) < 0) goto err; entry->prev = NULL; entry->next = dbase->cache; /* Link */ if (dbase->cache != NULL) dbase->cache->prev = entry; if (dbase->cache_tail == NULL) dbase->cache_tail = entry; dbase->cache = entry; dbase->cache_sz++; return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: ERR(handle, "could not cache record"); free(entry); return STATUS_ERR; } void dbase_llist_drop_cache(dbase_llist_t * dbase) { if (dbase->cache_serial < 0) return; cache_entry_t *prev, *ptr = dbase->cache; while (ptr != NULL) { prev = ptr; ptr = ptr->next; dbase->rtable->free(prev->data); free(prev); } dbase->cache_serial = -1; dbase->modified = 0; } int dbase_llist_set_serial(semanage_handle_t * handle, dbase_llist_t * dbase) { int cache_serial = handle->funcs->get_serial(handle); if (cache_serial < 0) { ERR(handle, "could not update cache serial"); return STATUS_ERR; } dbase->cache_serial = cache_serial; return STATUS_SUCCESS; } /* Helper for finding records in the cache */ static int dbase_llist_cache_locate(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key, cache_entry_t ** entry) { cache_entry_t *ptr; /* Implemented in parent */ if (dbase->dtable->cache(handle, dbase) < 0) goto err; for (ptr = dbase->cache; ptr != NULL; ptr = ptr->next) { if (!dbase->rtable->compare(ptr->data, key)) { *entry = ptr; return STATUS_SUCCESS; } } return STATUS_NODATA; err: ERR(handle, "could not complete cache lookup"); return STATUS_ERR; } int dbase_llist_exists(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key, int *response) { cache_entry_t *entry; int status; status = dbase_llist_cache_locate(handle, dbase, key, &entry); if (status < 0) goto err; *response = (status != STATUS_NODATA); return STATUS_SUCCESS; err: ERR(handle, "could not check if record exists"); return STATUS_ERR; } int dbase_llist_add(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key __attribute__ ((unused)), const record_t * data) { if (dbase_llist_cache_prepend(handle, dbase, data) < 0) goto err; key = NULL; dbase->modified = 1; return STATUS_SUCCESS; err: ERR(handle, "could not add record to the database"); return STATUS_ERR; } int dbase_llist_set(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key, const record_t * data) { cache_entry_t *entry; int status; status = dbase_llist_cache_locate(handle, dbase, key, &entry); if (status < 0) goto err; if (status == STATUS_NODATA) { ERR(handle, "record not found in the database"); goto err; } else { dbase->rtable->free(entry->data); if (dbase->rtable->clone(handle, data, &entry->data) < 0) goto err; } dbase->modified = 1; return STATUS_SUCCESS; err: ERR(handle, "could not set record value"); return STATUS_ERR; } int dbase_llist_modify(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key, const record_t * data) { cache_entry_t *entry; int status; status = dbase_llist_cache_locate(handle, dbase, key, &entry); if (status < 0) goto err; if (status == STATUS_NODATA) { if (dbase_llist_cache_prepend(handle, dbase, data) < 0) goto err; } else { dbase->rtable->free(entry->data); if (dbase->rtable->clone(handle, data, &entry->data) < 0) goto err; } dbase->modified = 1; return STATUS_SUCCESS; err: ERR(handle, "could not modify record value"); return STATUS_ERR; } hidden int dbase_llist_count(semanage_handle_t * handle __attribute__ ((unused)), dbase_llist_t * dbase, unsigned int *response) { *response = dbase->cache_sz; handle = NULL; return STATUS_SUCCESS; } int dbase_llist_query(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key, record_t ** response) { cache_entry_t *entry; int status; status = dbase_llist_cache_locate(handle, dbase, key, &entry); if (status < 0 || status == STATUS_NODATA) goto err; if (dbase->rtable->clone(handle, entry->data, response) < 0) goto err; return STATUS_SUCCESS; err: ERR(handle, "could not query record value"); return STATUS_ERR; } int dbase_llist_iterate(semanage_handle_t * handle, dbase_llist_t * dbase, int (*fn) (const record_t * record, void *fn_arg), void *arg) { int rc; cache_entry_t *ptr; for (ptr = dbase->cache_tail; ptr != NULL; ptr = ptr->prev) { rc = fn(ptr->data, arg); if (rc < 0) goto err; else if (rc > 1) break; } return STATUS_SUCCESS; err: ERR(handle, "could not iterate over records"); return STATUS_ERR; } int dbase_llist_del(semanage_handle_t * handle __attribute__ ((unused)), dbase_llist_t * dbase, const record_key_t * key) { cache_entry_t *ptr, *prev = NULL; for (ptr = dbase->cache; ptr != NULL; ptr = ptr->next) { if (!dbase->rtable->compare(ptr->data, key)) { if (prev != NULL) prev->next = ptr->next; else dbase->cache = ptr->next; if (ptr->next != NULL) ptr->next->prev = ptr->prev; else dbase->cache_tail = ptr->prev; dbase->rtable->free(ptr->data); dbase->cache_sz--; free(ptr); dbase->modified = 1; return STATUS_SUCCESS; } else prev = ptr; } handle = NULL; return STATUS_SUCCESS; } int dbase_llist_clear(semanage_handle_t * handle, dbase_llist_t * dbase) { int old_serial = dbase->cache_serial; if (dbase_llist_set_serial(handle, dbase) < 0) { ERR(handle, "could not set serial of cleared dbase"); return STATUS_ERR; } if (old_serial >= 0) { cache_entry_t *prev, *ptr = dbase->cache; while (ptr != NULL) { prev = ptr; ptr = ptr->next; dbase->rtable->free(prev->data); free(prev); } } dbase->cache = NULL; dbase->cache_tail = NULL; dbase->cache_sz = 0; dbase->modified = 1; return STATUS_SUCCESS; } int dbase_llist_list(semanage_handle_t * handle, dbase_llist_t * dbase, record_t *** records, unsigned int *count) { cache_entry_t *ptr; record_t **tmp_records = NULL; unsigned int tmp_count; int i = 0; tmp_count = dbase->cache_sz; if (tmp_count > 0) { tmp_records = (record_t **) calloc(tmp_count, sizeof(record_t *)); if (tmp_records == NULL) goto omem; for (ptr = dbase->cache_tail; ptr != NULL; ptr = ptr->prev) { if (dbase->rtable->clone(handle, ptr->data, &tmp_records[i]) < 0) goto err; i++; } } *records = tmp_records; *count = tmp_count; return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: if (tmp_records) { for (; i >= 0; i--) dbase->rtable->free(tmp_records[i]); free(tmp_records); } ERR(handle, "could not allocate record array"); return STATUS_ERR; } libsemanage-2.3/src/database_llist.h000066400000000000000000000062001233221606300175340ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_DATABASE_LLIST_INTERNAL_H_ #define _SEMANAGE_DATABASE_LLIST_INTERNAL_H_ #include "database.h" #include "handle.h" /* Representation of the database once loaded in memory */ typedef struct cache_entry { record_t *data; struct cache_entry *prev; struct cache_entry *next; } cache_entry_t; /* LLIST dbase */ typedef struct dbase_llist { /* Method tables */ record_table_t *rtable; dbase_table_t *dtable; /* In-memory representation (cache) */ cache_entry_t *cache; cache_entry_t *cache_tail; unsigned int cache_sz; int cache_serial; int modified; } dbase_llist_t; /* Helpers for internal use only */ static inline void dbase_llist_cache_init(dbase_llist_t * dbase) { dbase->cache = NULL; dbase->cache_tail = NULL; dbase->cache_sz = 0; dbase->cache_serial = -1; dbase->modified = 0; } static inline void dbase_llist_init(dbase_llist_t * dbase, record_table_t * rtable, dbase_table_t * dtable) { dbase->rtable = rtable; dbase->dtable = dtable; dbase_llist_cache_init(dbase); } extern int dbase_llist_cache_prepend(semanage_handle_t * handle, dbase_llist_t * dbase, const record_t * data); extern int dbase_llist_needs_resync(semanage_handle_t * handle, dbase_llist_t * dbase); extern int dbase_llist_set_serial(semanage_handle_t * handle, dbase_llist_t * dbase); static inline void dbase_llist_set_modified(dbase_llist_t * dbase, int status) { dbase->modified = status; } /* LLIST - cache/transactions */ extern void dbase_llist_drop_cache(dbase_llist_t * dbase); static inline int dbase_llist_is_modified(dbase_llist_t * dbase) { return dbase->modified; } /* LLIST - polymorphism */ static inline record_table_t *dbase_llist_get_rtable(dbase_llist_t * dbase) { return dbase->rtable; } /* LLIST - dbase API */ extern int dbase_llist_exists(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key, int *response); extern int dbase_llist_add(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key, const record_t * data); extern int dbase_llist_set(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key, const record_t * data); extern int dbase_llist_modify(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key, const record_t * data); extern int dbase_llist_count(semanage_handle_t * handle, dbase_llist_t * dbase, unsigned int *response); extern int dbase_llist_query(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key, record_t ** response); extern int dbase_llist_iterate(semanage_handle_t * handle, dbase_llist_t * dbase, int (*fn) (const record_t * record, void *fn_arg), void *arg); extern int dbase_llist_del(semanage_handle_t * handle, dbase_llist_t * dbase, const record_key_t * key); extern int dbase_llist_clear(semanage_handle_t * handle, dbase_llist_t * dbase); extern int dbase_llist_list(semanage_handle_t * handle, dbase_llist_t * dbase, record_t *** records, unsigned int *count); #endif libsemanage-2.3/src/database_policydb.c000066400000000000000000000250431233221606300202130ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: dbase_policydb_t (Policy) * Implements: dbase_t (Database) */ struct dbase_policydb; typedef struct dbase_policydb dbase_t; #define DBASE_DEFINED #include #include #include #include #include #include #include #include "database_policydb.h" #include "semanage_store.h" #include "handle.h" #include "debug.h" /* POLICYDB dbase */ struct dbase_policydb { /* Backing file suffix */ const char *suffix; /* Base record table */ record_table_t *rtable; /* Policy extensions */ record_policydb_table_t *rptable; sepol_policydb_t *policydb; int cache_serial; int modified; int attached; }; static void dbase_policydb_drop_cache(dbase_policydb_t * dbase) { if (dbase->cache_serial >= 0) { sepol_policydb_free(dbase->policydb); dbase->cache_serial = -1; dbase->modified = 0; } } static int dbase_policydb_set_serial(semanage_handle_t * handle, dbase_policydb_t * dbase) { int cache_serial = handle->funcs->get_serial(handle); if (cache_serial < 0) { ERR(handle, "could not update cache serial"); return STATUS_ERR; } dbase->cache_serial = cache_serial; return STATUS_SUCCESS; } static int dbase_policydb_needs_resync(semanage_handle_t * handle, dbase_policydb_t * dbase) { int cache_serial; if (dbase->cache_serial < 0) return 1; cache_serial = handle->funcs->get_serial(handle); if (cache_serial < 0) return 1; if (cache_serial != dbase->cache_serial) { dbase_policydb_drop_cache(dbase); dbase->cache_serial = -1; return 1; } return 0; } static int construct_filename(semanage_handle_t * handle, dbase_policydb_t * dbase, char **filename) { const char *path = (handle->is_in_transaction) ? semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL) : semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL); size_t fname_length = strlen(path) + strlen(dbase->suffix) + 2; char *fname = malloc(fname_length); if (!fname) { ERR(handle, "out of memory, could not construct database name"); return STATUS_ERR; } snprintf(fname, fname_length, "%s/%s", path, dbase->suffix); *filename = fname; return STATUS_SUCCESS; } static int dbase_policydb_cache(semanage_handle_t * handle, dbase_policydb_t * dbase) { FILE *fp = NULL; sepol_policydb_t *policydb = NULL; sepol_policy_file_t *pf = NULL; char *fname = NULL; /* Check if cache is needed */ if (dbase->attached) return STATUS_SUCCESS; if (!dbase_policydb_needs_resync(handle, dbase)) return STATUS_SUCCESS; if (construct_filename(handle, dbase, &fname) < 0) goto err; if (sepol_policydb_create(&policydb) < 0) { ERR(handle, "could not create policydb object"); goto err; } /* Try opening file * ENOENT is not fatal - we just create an empty policydb */ fp = fopen(fname, "rb"); if (fp == NULL && errno != ENOENT) { ERR(handle, "could not open %s for reading: %s", fname, strerror(errno)); goto err; } /* If the file was opened successfully, read a policydb */ if (fp != NULL) { __fsetlocking(fp, FSETLOCKING_BYCALLER); if (sepol_policy_file_create(&pf) < 0) { ERR(handle, "could not create policy file object"); goto err; } sepol_policy_file_set_fp(pf, fp); sepol_policy_file_set_handle(pf, handle->sepolh); if (sepol_policydb_read(policydb, pf) < 0) goto err; sepol_policy_file_free(pf); fclose(fp); fp = NULL; } /* Update cache serial */ if (dbase_policydb_set_serial(handle, dbase) < 0) goto err; /* Update the database policydb */ dbase->policydb = policydb; free(fname); return STATUS_SUCCESS; err: ERR(handle, "could not cache policy database"); if (fp) fclose(fp); sepol_policydb_free(policydb); sepol_policy_file_free(pf); free(fname); return STATUS_ERR; } static int dbase_policydb_flush(semanage_handle_t * handle __attribute__ ((unused)), dbase_policydb_t * dbase) { if (!dbase->modified) return STATUS_SUCCESS; dbase->modified = 0; /* Stub */ handle = NULL; return STATUS_ERR; } /* Check if modified */ static int dbase_policydb_is_modified(dbase_policydb_t * dbase) { return dbase->modified; } int dbase_policydb_init(semanage_handle_t * handle, const char *suffix, record_table_t * rtable, record_policydb_table_t * rptable, dbase_policydb_t ** dbase) { dbase_policydb_t *tmp_dbase = (dbase_policydb_t *) malloc(sizeof(dbase_policydb_t)); if (!tmp_dbase) goto omem; tmp_dbase->suffix = suffix; tmp_dbase->rtable = rtable; tmp_dbase->rptable = rptable; tmp_dbase->policydb = NULL; tmp_dbase->cache_serial = -1; tmp_dbase->modified = 0; tmp_dbase->attached = 0; *dbase = tmp_dbase; return STATUS_SUCCESS; omem: ERR(handle, "out of memory, could not initialize policy database"); free(tmp_dbase); return STATUS_ERR; } /* Release dbase resources */ void dbase_policydb_release(dbase_policydb_t * dbase) { dbase_policydb_drop_cache(dbase); free(dbase); } /* Attach to a shared policydb. * This implies drop_cache(), * and prevents flush() and drop_cache() * until detached. */ void dbase_policydb_attach(dbase_policydb_t * dbase, sepol_policydb_t * policydb) { dbase->attached = 1; dbase_policydb_drop_cache(dbase); dbase->policydb = policydb; } /* Detach from a shared policdb. * This implies drop_cache. */ void dbase_policydb_detach(dbase_policydb_t * dbase) { dbase->attached = 0; dbase->modified = 0; } static int dbase_policydb_add(semanage_handle_t * handle, dbase_policydb_t * dbase, const record_key_t * key, const record_t * data) { if (dbase->rptable->add(handle->sepolh, dbase->policydb, key, data) < 0) goto err; dbase->modified = 1; return STATUS_SUCCESS; err: ERR(handle, "could not add record to the database"); return STATUS_ERR; } static int dbase_policydb_set(semanage_handle_t * handle, dbase_policydb_t * dbase, const record_key_t * key, const record_t * data) { if (dbase->rptable->set(handle->sepolh, dbase->policydb, key, data) < 0) goto err; dbase->modified = 1; return STATUS_SUCCESS; err: ERR(handle, "could not set record value"); return STATUS_ERR; } static int dbase_policydb_modify(semanage_handle_t * handle, dbase_policydb_t * dbase, const record_key_t * key, const record_t * data) { if (dbase->rptable->modify(handle->sepolh, dbase->policydb, key, data) < 0) goto err; dbase->modified = 1; return STATUS_SUCCESS; err: ERR(handle, "could not modify record value"); return STATUS_ERR; } static int dbase_policydb_del(semanage_handle_t * handle __attribute__ ((unused)), dbase_policydb_t * dbase __attribute__ ((unused)), const record_key_t * key __attribute__ ((unused))) { /* Stub */ key = NULL; handle = NULL; dbase = NULL; return STATUS_ERR; } static int dbase_policydb_clear(semanage_handle_t * handle __attribute__ ((unused)), dbase_policydb_t * dbase __attribute__ ((unused))) { /* Stub */ handle = NULL; dbase = NULL; return STATUS_ERR; } static int dbase_policydb_query(semanage_handle_t * handle, dbase_policydb_t * dbase, const record_key_t * key, record_t ** response) { if (dbase->rptable->query(handle->sepolh, dbase->policydb, key, response) < 0) goto err; return STATUS_SUCCESS; err: ERR(handle, "could not query record value"); return STATUS_ERR; } static int dbase_policydb_exists(semanage_handle_t * handle, dbase_policydb_t * dbase, const record_key_t * key, int *response) { if (dbase->rptable->exists(handle->sepolh, dbase->policydb, key, response) < 0) goto err; return STATUS_SUCCESS; err: ERR(handle, "could not check if record exists"); return STATUS_ERR; } static int dbase_policydb_count(semanage_handle_t * handle, dbase_policydb_t * dbase, unsigned int *response) { if (dbase->rptable->count(handle->sepolh, dbase->policydb, response) < 0) goto err; return STATUS_SUCCESS; err: ERR(handle, "could not count the database records"); return STATUS_ERR; } static int dbase_policydb_iterate(semanage_handle_t * handle, dbase_policydb_t * dbase, int (*fn) (const record_t * record, void *fn_arg), void *arg) { if (dbase->rptable->iterate(handle->sepolh, dbase->policydb, fn, arg) < 0) goto err; return STATUS_SUCCESS; err: ERR(handle, "could not iterate over records"); return STATUS_ERR; } struct list_handler_arg { semanage_handle_t *handle; record_table_t *rtable; record_t **records; int pos; }; static int list_handler(const record_t * record, void *varg) { struct list_handler_arg *arg = (struct list_handler_arg *)varg; if (arg->rtable->clone(arg->handle, record, &arg->records[arg->pos]) < 0) return -1; arg->pos++; return 0; } static int dbase_policydb_list(semanage_handle_t * handle, dbase_t * dbase, record_t *** records, unsigned int *count) { record_t **tmp_records = NULL; unsigned int tmp_count; struct list_handler_arg list_arg; list_arg.pos = 0; list_arg.rtable = dbase->rtable; list_arg.handle = handle; if (dbase->rptable->count(handle->sepolh, dbase->policydb, &tmp_count) < 0) goto err; if (tmp_count > 0) { tmp_records = (record_t **) calloc(tmp_count, sizeof(record_t *)); if (tmp_records == NULL) goto omem; list_arg.records = tmp_records; if (dbase->rptable->iterate(handle->sepolh, dbase->policydb, list_handler, &list_arg) < 0) { ERR(handle, "list handler could not extract record"); goto err; } } *records = tmp_records; *count = tmp_count; return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: if (tmp_records) { for (; list_arg.pos >= 0; list_arg.pos--) dbase->rtable->free(tmp_records[list_arg.pos]); free(tmp_records); } ERR(handle, "could not list records"); return STATUS_ERR; } static record_table_t *dbase_policydb_get_rtable(dbase_policydb_t * dbase) { return dbase->rtable; } /* POLICYDB dbase - method table implementation */ dbase_table_t SEMANAGE_POLICYDB_DTABLE = { /* Cache/Transactions */ .cache = dbase_policydb_cache, .drop_cache = dbase_policydb_drop_cache, .flush = dbase_policydb_flush, .is_modified = dbase_policydb_is_modified, /* Database Functionality */ .iterate = dbase_policydb_iterate, .exists = dbase_policydb_exists, .list = dbase_policydb_list, .add = dbase_policydb_add, .set = dbase_policydb_set, .del = dbase_policydb_del, .clear = dbase_policydb_clear, .modify = dbase_policydb_modify, .query = dbase_policydb_query, .count = dbase_policydb_count, /* Polymorphism */ .get_rtable = dbase_policydb_get_rtable }; libsemanage-2.3/src/database_policydb.h000066400000000000000000000072531233221606300202230ustar00rootroot00000000000000/* * Copyright (C) 2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_DATABASE_POLICYDB_INTERNAL_H_ #define _SEMANAGE_DATABASE_POLICYDB_INTERNAL_H_ #include #include #include "database.h" #include "handle.h" struct dbase_policydb; typedef struct dbase_policydb dbase_policydb_t; typedef int (*record_policydb_table_add_t) (sepol_handle_t * h, sepol_policydb_t * p, const record_key_t * rkey, const record_t * record); typedef int (*record_policydb_table_modify_t) (sepol_handle_t * h, sepol_policydb_t * p, const record_key_t * rkey, const record_t * record); typedef int (*record_policydb_table_set_t) (sepol_handle_t * h, sepol_policydb_t * p, const record_key_t * rkey, const record_t * record); typedef int (*record_policydb_table_query_t) (sepol_handle_t * h, const sepol_policydb_t * p, const record_key_t * rkey, record_t ** response); typedef int (*record_policydb_table_count_t) (sepol_handle_t * h, const sepol_policydb_t * p, unsigned int *response); typedef int (*record_policydb_table_exists_t) (sepol_handle_t * h, const sepol_policydb_t * p, const record_key_t * rkey, int *response); typedef int (*record_policydb_table_iterate_t) (sepol_handle_t * h, const sepol_policydb_t * p, int (*fn) (const record_t * r, void *fn_arg), void *arg); /* POLICYDB extension to RECORD interface - method table */ typedef struct record_policydb_table { /* Add policy record */ record_policydb_table_add_t add; /* Modify policy record, or add if * the key isn't found */ record_policydb_table_modify_t modify; /* Set policy record */ record_policydb_table_set_t set; /* Query policy record - return the record * or NULL if it isn't found */ record_policydb_table_query_t query; /* Count records */ record_policydb_table_count_t count; /* Check if a record exists */ record_policydb_table_exists_t exists; /* Iterate over records */ record_policydb_table_iterate_t iterate; } record_policydb_table_t; /* Initialize database */ extern int dbase_policydb_init(semanage_handle_t * handle, const char *suffix, record_table_t * rtable, record_policydb_table_t * rptable, dbase_policydb_t ** dbase); /* Attach to a shared policydb. * This implies drop_cache(). * and prevents flush() and drop_cache() * until detached. */ extern void dbase_policydb_attach(dbase_policydb_t * dbase, sepol_policydb_t * policydb); /* Detach from a shared policdb. * This implies drop_cache. */ extern void dbase_policydb_detach(dbase_policydb_t * dbase); /* Release allocated resources */ extern void dbase_policydb_release(dbase_policydb_t * dbase); /* POLICYDB database - method table implementation */ extern dbase_table_t SEMANAGE_POLICYDB_DTABLE; #endif libsemanage-2.3/src/debug.c000066400000000000000000000063001233221606300156430ustar00rootroot00000000000000/* Author: Joshua Brindle * Ivan Gyurdiev * * Copyright (C) 2004-2005 Tresys Technology, LLC * Copyright (C) 2005 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include "handle.h" #include "debug.h" int semanage_msg_get_level(semanage_handle_t * handle) { return handle->msg_level; } hidden_def(semanage_msg_get_level) const char *semanage_msg_get_channel(semanage_handle_t * handle) { return handle->msg_channel; } hidden_def(semanage_msg_get_channel) const char *semanage_msg_get_fname(semanage_handle_t * handle) { return handle->msg_fname; } hidden_def(semanage_msg_get_fname) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif void hidden semanage_msg_default_handler(void *varg __attribute__ ((unused)), semanage_handle_t * handle, const char *fmt, ...) { FILE *stream = NULL; int errsv = 0; switch (semanage_msg_get_level(handle)) { case SEMANAGE_MSG_ERR: stream = stderr; errsv = errno; break; case SEMANAGE_MSG_WARN: stream = stderr; break; default: stream = stdout; break; } fprintf(stream, "%s.%s: ", semanage_msg_get_channel(handle), semanage_msg_get_fname(handle)); va_list ap; va_start(ap, fmt); vfprintf(stream, fmt, ap); va_end(ap); if (errsv && errsv != ENOMEM) fprintf(stream, " (%s).", strerror(errsv)); fprintf(stream, "\n"); varg = NULL; } #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif void hidden semanage_msg_relay_handler(void *varg, sepol_handle_t * sepolh, const char *fmt, ...) { va_list ap; semanage_handle_t *sh = varg; char buffer[1024]; if (!sh->msg_callback) return; va_start(ap, fmt); vsnprintf(buffer, sizeof(buffer), fmt, ap); va_end(ap); sh->msg_fname = sepol_msg_get_fname(sepolh); sh->msg_channel = sepol_msg_get_channel(sepolh); sh->msg_level = sepol_msg_get_level(sepolh); /* XXX should map values */ sh->msg_callback(sh->msg_callback_arg, sh, "%s", buffer); return; } extern void semanage_msg_set_callback(semanage_handle_t * handle, #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif void (*msg_callback) (void *varg, semanage_handle_t * handle, const char *fmt, ...), void *msg_callback_arg) { handle->msg_callback = msg_callback; handle->msg_callback_arg = msg_callback_arg; } libsemanage-2.3/src/debug.h000066400000000000000000000053611233221606300156560ustar00rootroot00000000000000/* Author: Joshua Brindle * Jason Tang * Ivan Gyurdiev * * Copyright (C) 2005 Tresys Technology, LLC * Copyright (C) 2005 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SEMANAGE_INTERNAL_DEBUG_H_ #define _SEMANAGE_INTERNAL_DEBUG_H_ #include #include #include #include "handle.h" #include "dso.h" #define STATUS_SUCCESS 0 #define STATUS_ERR -1 #define STATUS_NODATA 1 #define msg_write(handle_arg, level_arg, \ channel_arg, func_arg, ...) do { \ \ if ((handle_arg)->msg_callback) { \ (handle_arg)->msg_fname = func_arg; \ (handle_arg)->msg_channel = channel_arg; \ (handle_arg)->msg_level = level_arg; \ \ (handle_arg)->msg_callback( \ (handle_arg)->msg_callback_arg, \ handle_arg, __VA_ARGS__); \ } \ } while(0) #define ERR(handle, ...) \ msg_write(handle, SEMANAGE_MSG_ERR, "libsemanage", \ __FUNCTION__, __VA_ARGS__) #define INFO(handle, ...) \ msg_write(handle, SEMANAGE_MSG_INFO, "libsemanage", \ __FUNCTION__, __VA_ARGS__) #define WARN(handle, ...) \ msg_write(handle, SEMANAGE_MSG_WARN, "libsemanage", \ __FUNCTION__, __VA_ARGS__) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif extern void hidden semanage_msg_default_handler(void *varg, semanage_handle_t * handle, const char *fmt, ...); #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif extern void hidden semanage_msg_relay_handler(void *varg, sepol_handle_t * handle, const char *fmt, ...); hidden_proto(semanage_msg_get_channel) hidden_proto(semanage_msg_get_fname) hidden_proto(semanage_msg_get_level) #endif libsemanage-2.3/src/direct_api.c000066400000000000000000001272171233221606300166730ustar00rootroot00000000000000/* Author: Jason Tang * Christopher Ashworth * * Copyright (C) 2004-2006 Tresys Technology, LLC * Copyright (C) 2005-2011 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "user_internal.h" #include "seuser_internal.h" #include "port_internal.h" #include "iface_internal.h" #include "boolean_internal.h" #include "fcontext_internal.h" #include "node_internal.h" #include "genhomedircon.h" #include "debug.h" #include "handle.h" #include "modules.h" #include "direct_api.h" #include "semanage_store.h" #include "database_policydb.h" #include "policy.h" #include static void semanage_direct_destroy(semanage_handle_t * sh); static int semanage_direct_disconnect(semanage_handle_t * sh); static int semanage_direct_begintrans(semanage_handle_t * sh); static int semanage_direct_commit(semanage_handle_t * sh); static int semanage_direct_install(semanage_handle_t * sh, char *data, size_t data_len); static int semanage_direct_install_file(semanage_handle_t * sh, const char *module_name); static int semanage_direct_upgrade(semanage_handle_t * sh, char *data, size_t data_len); static int semanage_direct_upgrade_file(semanage_handle_t * sh, const char *module_name); static int semanage_direct_install_base(semanage_handle_t * sh, char *base_data, size_t data_len); static int semanage_direct_install_base_file(semanage_handle_t * sh, const char *module_name); static int semanage_direct_enable(semanage_handle_t * sh, char *module_name); static int semanage_direct_disable(semanage_handle_t * sh, char *module_name); static int semanage_direct_remove(semanage_handle_t * sh, char *module_name); static int semanage_direct_list(semanage_handle_t * sh, semanage_module_info_t ** modinfo, int *num_modules); static struct semanage_policy_table direct_funcs = { .get_serial = semanage_direct_get_serial, .destroy = semanage_direct_destroy, .disconnect = semanage_direct_disconnect, .begin_trans = semanage_direct_begintrans, .commit = semanage_direct_commit, .install = semanage_direct_install, .install_file = semanage_direct_install_file, .upgrade = semanage_direct_upgrade, .upgrade_file = semanage_direct_upgrade_file, .install_base = semanage_direct_install_base, .install_base_file = semanage_direct_install_base_file, .enable = semanage_direct_enable, .disable = semanage_direct_disable, .remove = semanage_direct_remove, .list = semanage_direct_list }; int semanage_direct_is_managed(semanage_handle_t * sh) { char polpath[PATH_MAX]; snprintf(polpath, PATH_MAX, "%s%s", semanage_selinux_path(), sh->conf->store_path); if (semanage_check_init(polpath)) goto err; if (semanage_access_check(sh) < 0) return 0; return 1; err: ERR(sh, "could not check whether policy is managed"); return STATUS_ERR; } /* Check that the module store exists, creating it if necessary. */ int semanage_direct_connect(semanage_handle_t * sh) { char polpath[PATH_MAX]; const char *path; snprintf(polpath, PATH_MAX, "%s%s", semanage_selinux_path(), sh->conf->store_path); if (semanage_check_init(polpath)) goto err; if (sh->create_store) if (semanage_create_store(sh, 1)) goto err; if (semanage_access_check(sh) < SEMANAGE_CAN_READ) goto err; sh->u.direct.translock_file_fd = -1; sh->u.direct.activelock_file_fd = -1; /* set up function pointers */ sh->funcs = &direct_funcs; /* Object databases: local modifications */ if (user_base_file_dbase_init(sh, semanage_fname(SEMANAGE_USERS_BASE_LOCAL), semanage_user_base_dbase_local(sh)) < 0) goto err; if (user_extra_file_dbase_init(sh, semanage_fname (SEMANAGE_USERS_EXTRA_LOCAL), semanage_user_extra_dbase_local(sh)) < 0) goto err; if (user_join_dbase_init(sh, semanage_user_base_dbase_local(sh), semanage_user_extra_dbase_local(sh), semanage_user_dbase_local(sh)) < 0) goto err; if (port_file_dbase_init(sh, semanage_fname(SEMANAGE_PORTS_LOCAL), semanage_port_dbase_local(sh)) < 0) goto err; if (iface_file_dbase_init(sh, semanage_fname(SEMANAGE_INTERFACES_LOCAL), semanage_iface_dbase_local(sh)) < 0) goto err; if (bool_file_dbase_init(sh, semanage_fname(SEMANAGE_BOOLEANS_LOCAL), semanage_bool_dbase_local(sh)) < 0) goto err; if (fcontext_file_dbase_init(sh, semanage_fname(SEMANAGE_FC_LOCAL), semanage_fcontext_dbase_local(sh)) < 0) goto err; if (seuser_file_dbase_init(sh, semanage_fname(SEMANAGE_SEUSERS_LOCAL), semanage_seuser_dbase_local(sh)) < 0) goto err; if (node_file_dbase_init(sh, semanage_fname(SEMANAGE_NODES_LOCAL), semanage_node_dbase_local(sh)) < 0) goto err; /* Object databases: local modifications + policy */ if (user_base_policydb_dbase_init(sh, semanage_user_base_dbase_policy(sh)) < 0) goto err; if (user_extra_file_dbase_init(sh, semanage_fname(SEMANAGE_USERS_EXTRA), semanage_user_extra_dbase_policy(sh)) < 0) goto err; if (user_join_dbase_init(sh, semanage_user_base_dbase_policy(sh), semanage_user_extra_dbase_policy(sh), semanage_user_dbase_policy(sh)) < 0) goto err; if (port_policydb_dbase_init(sh, semanage_port_dbase_policy(sh)) < 0) goto err; if (iface_policydb_dbase_init(sh, semanage_iface_dbase_policy(sh)) < 0) goto err; if (bool_policydb_dbase_init(sh, semanage_bool_dbase_policy(sh)) < 0) goto err; if (fcontext_file_dbase_init(sh, semanage_fname(SEMANAGE_FC), semanage_fcontext_dbase_policy(sh)) < 0) goto err; if (seuser_file_dbase_init(sh, semanage_fname(SEMANAGE_SEUSERS), semanage_seuser_dbase_policy(sh)) < 0) goto err; if (node_policydb_dbase_init(sh, semanage_node_dbase_policy(sh)) < 0) goto err; /* Active kernel policy */ if (bool_activedb_dbase_init(sh, semanage_bool_dbase_active(sh)) < 0) goto err; /* set the disable dontaudit value */ path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_DISABLE_DONTAUDIT); if (access(path, F_OK) == 0) sepol_set_disable_dontaudit(sh->sepolh, 1); else sepol_set_disable_dontaudit(sh->sepolh, 0); return STATUS_SUCCESS; err: ERR(sh, "could not establish direct connection"); return STATUS_ERR; } static void semanage_direct_destroy(semanage_handle_t * sh __attribute__ ((unused))) { /* do nothing */ sh = NULL; } static int semanage_direct_disconnect(semanage_handle_t * sh) { /* destroy transaction */ if (sh->is_in_transaction) { /* destroy sandbox */ if (semanage_remove_directory (semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)) < 0) { ERR(sh, "Could not cleanly remove sandbox %s.", semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)); return -1; } semanage_release_trans_lock(sh); } /* Release object databases: local modifications */ user_base_file_dbase_release(semanage_user_base_dbase_local(sh)); user_extra_file_dbase_release(semanage_user_extra_dbase_local(sh)); user_join_dbase_release(semanage_user_dbase_local(sh)); port_file_dbase_release(semanage_port_dbase_local(sh)); iface_file_dbase_release(semanage_iface_dbase_local(sh)); bool_file_dbase_release(semanage_bool_dbase_local(sh)); fcontext_file_dbase_release(semanage_fcontext_dbase_local(sh)); seuser_file_dbase_release(semanage_seuser_dbase_local(sh)); node_file_dbase_release(semanage_node_dbase_local(sh)); /* Release object databases: local modifications + policy */ user_base_policydb_dbase_release(semanage_user_base_dbase_policy(sh)); user_extra_file_dbase_release(semanage_user_extra_dbase_policy(sh)); user_join_dbase_release(semanage_user_dbase_policy(sh)); port_policydb_dbase_release(semanage_port_dbase_policy(sh)); iface_policydb_dbase_release(semanage_iface_dbase_policy(sh)); bool_policydb_dbase_release(semanage_bool_dbase_policy(sh)); fcontext_file_dbase_release(semanage_fcontext_dbase_policy(sh)); seuser_file_dbase_release(semanage_seuser_dbase_policy(sh)); node_policydb_dbase_release(semanage_node_dbase_policy(sh)); /* Release object databases: active kernel policy */ bool_activedb_dbase_release(semanage_bool_dbase_active(sh)); return 0; } static int semanage_direct_begintrans(semanage_handle_t * sh) { if (semanage_access_check(sh) != SEMANAGE_CAN_WRITE) { return -1; } if (semanage_get_trans_lock(sh) < 0) { return -1; } if ((semanage_make_sandbox(sh)) < 0) { return -1; } return 0; } /********************* utility functions *********************/ /* Takes a module stored in 'module_data' and parses its headers. * Sets reference variables 'filename' to module's fully qualified * path name into the sandbox, 'module_name' to module's name, and * 'version' to module's version. The caller is responsible for * free()ing 'filename', 'module_name', and 'version'; they will be * set to NULL upon entering this function. Returns 0 on success, -1 * if out of memory, or -2 if data did not represent a module. */ static int parse_module_headers(semanage_handle_t * sh, char *module_data, size_t data_len, char **module_name, char **version, char **filename) { struct sepol_policy_file *pf; int file_type; const char *module_path; *module_name = *version = *filename = NULL; if (sepol_policy_file_create(&pf)) { ERR(sh, "Out of memory!"); return -1; } sepol_policy_file_set_mem(pf, module_data, data_len); sepol_policy_file_set_handle(pf, sh->sepolh); if (module_data == NULL || data_len == 0 || sepol_module_package_info(pf, &file_type, module_name, version) == -1) { sepol_policy_file_free(pf); ERR(sh, "Could not parse module data."); return -2; } sepol_policy_file_free(pf); if (file_type != SEPOL_POLICY_MOD) { if (file_type == SEPOL_POLICY_BASE) ERR(sh, "Received a base module, expected a non-base module."); else ERR(sh, "Data did not represent a module."); return -2; } if ((module_path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES)) == NULL) { return -1; } if (asprintf(filename, "%s/%s.pp", module_path, *module_name) == -1) { ERR(sh, "Out of memory!"); return -1; } return 0; } /* Takes a base module stored in 'module_data' and parse its headers. * Returns 0 on success, -1 if out of memory, or -2 if data did not * represent a module. */ static int parse_base_headers(semanage_handle_t * sh, char *module_data, size_t data_len) { struct sepol_policy_file *pf; char *module_name = NULL, *version = NULL; int file_type; if (sepol_policy_file_create(&pf)) { ERR(sh, "Out of memory!"); return -1; } sepol_policy_file_set_mem(pf, module_data, data_len); sepol_policy_file_set_handle(pf, sh->sepolh); if (module_data == NULL || data_len == 0 || sepol_module_package_info(pf, &file_type, &module_name, &version) == -1) { sepol_policy_file_free(pf); ERR(sh, "Could not parse base module data."); return -2; } sepol_policy_file_free(pf); free(module_name); free(version); if (file_type != SEPOL_POLICY_BASE) { if (file_type == SEPOL_POLICY_MOD) ERR(sh, "Received a non-base module, expected a base module."); else ERR(sh, "Data did not represent a module."); return -2; } return 0; } #include #include #include #include /* bzip() a data to a file, returning the total number of compressed bytes * in the file. Returns -1 if file could not be compressed. */ static ssize_t bzip(semanage_handle_t *sh, const char *filename, char *data, size_t num_bytes) { BZFILE* b; size_t size = 1<<16; int bzerror; size_t total = 0; size_t len = 0; FILE *f; if ((f = fopen(filename, "wb")) == NULL) { return -1; } if (!sh->conf->bzip_blocksize) { if (fwrite(data, 1, num_bytes, f) < num_bytes) { fclose(f); return -1; } fclose(f); return num_bytes; } b = BZ2_bzWriteOpen( &bzerror, f, sh->conf->bzip_blocksize, 0, 0); if (bzerror != BZ_OK) { BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 ); return -1; } while ( num_bytes > total ) { if (num_bytes - total > size) { len = size; } else { len = num_bytes - total; } BZ2_bzWrite ( &bzerror, b, &data[total], len ); if (bzerror == BZ_IO_ERROR) { BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 ); return -1; } total += len; } BZ2_bzWriteClose ( &bzerror, b, 0, 0, 0 ); fclose(f); if (bzerror == BZ_IO_ERROR) { return -1; } return total; } #define BZ2_MAGICSTR "BZh" #define BZ2_MAGICLEN (sizeof(BZ2_MAGICSTR)-1) /* bunzip() a file to '*data', returning the total number of uncompressed bytes * in the file. Returns -1 if file could not be decompressed. */ ssize_t bunzip(semanage_handle_t *sh, FILE *f, char **data) { BZFILE* b; size_t nBuf; char buf[1<<18]; size_t size = sizeof(buf); int bzerror; size_t total=0; if (!sh->conf->bzip_blocksize) { bzerror = fread(buf, 1, BZ2_MAGICLEN, f); rewind(f); if ((bzerror != BZ2_MAGICLEN) || memcmp(buf, BZ2_MAGICSTR, BZ2_MAGICLEN)) return -1; /* fall through */ } b = BZ2_bzReadOpen ( &bzerror, f, 0, sh->conf->bzip_small, NULL, 0 ); if ( bzerror != BZ_OK ) { BZ2_bzReadClose ( &bzerror, b ); return -1; } char *uncompress = realloc(NULL, size); while ( bzerror == BZ_OK) { nBuf = BZ2_bzRead ( &bzerror, b, buf, sizeof(buf)); if (( bzerror == BZ_OK ) || ( bzerror == BZ_STREAM_END )) { if (total + nBuf > size) { size *= 2; uncompress = realloc(uncompress, size); } memcpy(&uncompress[total], buf, nBuf); total += nBuf; } } if ( bzerror != BZ_STREAM_END ) { BZ2_bzReadClose ( &bzerror, b ); free(uncompress); return -1; } BZ2_bzReadClose ( &bzerror, b ); *data = uncompress; return total; } /* mmap() a file to '*data', * If the file is bzip compressed map_file will uncompress * the file into '*data'. * Returns the total number of bytes in memory . * Returns -1 if file could not be opened or mapped. */ static ssize_t map_file(semanage_handle_t *sh, int fd, char **data, int *compressed) { ssize_t size = -1; char *uncompress; if ((size = bunzip(sh, fdopen(fd, "r"), &uncompress)) > 0) { *data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); if (*data == MAP_FAILED) { free(uncompress); return -1; } else { memcpy(*data, uncompress, size); } free(uncompress); *compressed = 1; } else { struct stat sb; if (fstat(fd, &sb) == -1 || (*data = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) { size = -1; } else { size = sb.st_size; } *compressed = 0; } return size; } static int dupfile( const char *dest, int src_fd) { int dest_fd = -1; int retval = 0; int cnt; char buf[1<<18]; if (lseek(src_fd, 0, SEEK_SET) == -1 ) return -1; if ((dest_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) { return -1; } while (( retval == 0 ) && ( cnt = read(src_fd, buf, sizeof(buf)))> 0 ) { if (write(dest_fd, buf, cnt) < cnt) retval = -1; } close(dest_fd); return retval; } /* Writes a block of data to a file. Returns 0 on success, -1 on * error. */ static int write_file(semanage_handle_t * sh, const char *filename, char *data, size_t num_bytes) { int out; if ((out = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) { ERR(sh, "Could not open %s for writing.", filename); return -1; } if (write(out, data, num_bytes) == -1) { ERR(sh, "Error while writing to %s.", filename); close(out); return -1; } close(out); return 0; } /* Writes a module (or a base) to the file given by a fully-qualified * 'filename'. Returns 0 on success, -1 if file could not be written. */ static int semanage_write_module(semanage_handle_t * sh, const char *filename, sepol_module_package_t * package) { struct sepol_policy_file *pf; FILE *outfile; int retval; if (sepol_policy_file_create(&pf)) { ERR(sh, "Out of memory!"); return -1; } if ((outfile = fopen(filename, "wb")) == NULL) { sepol_policy_file_free(pf); ERR(sh, "Could not open %s for writing.", filename); return -1; } __fsetlocking(outfile, FSETLOCKING_BYCALLER); sepol_policy_file_set_fp(pf, outfile); sepol_policy_file_set_handle(pf, sh->sepolh); retval = sepol_module_package_write(package, pf); fclose(outfile); sepol_policy_file_free(pf); if (retval == -1) { ERR(sh, "Error while writing module to %s.", filename); return -1; } return 0; } static int semanage_direct_update_user_extra(semanage_handle_t * sh, sepol_module_package_t *base ) { const char *ofilename = NULL; int retval = -1; dbase_config_t *pusers_extra = semanage_user_extra_dbase_policy(sh); if (sepol_module_package_get_user_extra_len(base)) { ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA); if (ofilename == NULL) { return retval; } retval = write_file(sh, ofilename, sepol_module_package_get_user_extra(base), sepol_module_package_get_user_extra_len(base)); if (retval < 0) return retval; pusers_extra->dtable->drop_cache(pusers_extra->dbase); } else { retval = pusers_extra->dtable->clear(sh, pusers_extra->dbase); } return retval; } static int semanage_direct_update_seuser(semanage_handle_t * sh, sepol_module_package_t *base ) { const char *ofilename = NULL; int retval = -1; dbase_config_t *pseusers = semanage_seuser_dbase_policy(sh); if (sepol_module_package_get_seusers_len(base)) { ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS); if (ofilename == NULL) { return -1; } retval = write_file(sh, ofilename, sepol_module_package_get_seusers(base), sepol_module_package_get_seusers_len(base)); if (retval < 0) return retval; pseusers->dtable->drop_cache(pseusers->dbase); } else { retval = pseusers->dtable->clear(sh, pseusers->dbase); } return retval; } /********************* direct API functions ********************/ /* Commits all changes in sandbox to the actual kernel policy. * Returns commit number on success, -1 on error. */ static int semanage_direct_commit(semanage_handle_t * sh) { char **mod_filenames = NULL; char *sorted_fc_buffer = NULL, *sorted_nc_buffer = NULL; size_t sorted_fc_buffer_len = 0, sorted_nc_buffer_len = 0; const char *linked_filename = NULL, *ofilename = NULL, *path; sepol_module_package_t *base = NULL; int retval = -1, num_modfiles = 0, i; sepol_policydb_t *out = NULL; /* Declare some variables */ int modified = 0, fcontexts_modified, ports_modified, seusers_modified, users_extra_modified, dontaudit_modified, preserve_tunables_modified; dbase_config_t *users = semanage_user_dbase_local(sh); dbase_config_t *users_base = semanage_user_base_dbase_local(sh); dbase_config_t *pusers_base = semanage_user_base_dbase_policy(sh); dbase_config_t *users_extra = semanage_user_extra_dbase_local(sh); dbase_config_t *ports = semanage_port_dbase_local(sh); dbase_config_t *pports = semanage_port_dbase_policy(sh); dbase_config_t *bools = semanage_bool_dbase_local(sh); dbase_config_t *pbools = semanage_bool_dbase_policy(sh); dbase_config_t *ifaces = semanage_iface_dbase_local(sh); dbase_config_t *pifaces = semanage_iface_dbase_policy(sh); dbase_config_t *nodes = semanage_node_dbase_local(sh); dbase_config_t *pnodes = semanage_node_dbase_policy(sh); dbase_config_t *fcontexts = semanage_fcontext_dbase_local(sh); dbase_config_t *pfcontexts = semanage_fcontext_dbase_policy(sh); dbase_config_t *seusers = semanage_seuser_dbase_local(sh); /* Create or remove the disable_dontaudit flag file. */ path = semanage_path(SEMANAGE_TMP, SEMANAGE_DISABLE_DONTAUDIT); if (access(path, F_OK) == 0) dontaudit_modified = !(sepol_get_disable_dontaudit(sh->sepolh) == 1); else dontaudit_modified = (sepol_get_disable_dontaudit(sh->sepolh) == 1); if (sepol_get_disable_dontaudit(sh->sepolh) == 1) { FILE *touch; touch = fopen(path, "w"); if (touch != NULL) { if (fclose(touch) != 0) { ERR(sh, "Error attempting to create disable_dontaudit flag."); goto cleanup; } } else { ERR(sh, "Error attempting to create disable_dontaudit flag."); goto cleanup; } } else { if (remove(path) == -1 && errno != ENOENT) { ERR(sh, "Error removing the disable_dontaudit flag."); goto cleanup; } } /* Create or remove the preserve_tunables flag file. */ path = semanage_path(SEMANAGE_TMP, SEMANAGE_PRESERVE_TUNABLES); if (access(path, F_OK) == 0) preserve_tunables_modified = !(sepol_get_preserve_tunables(sh->sepolh) == 1); else preserve_tunables_modified = (sepol_get_preserve_tunables(sh->sepolh) == 1); if (sepol_get_preserve_tunables(sh->sepolh) == 1) { FILE *touch; touch = fopen(path, "w"); if (touch != NULL) { if (fclose(touch) != 0) { ERR(sh, "Error attempting to create preserve_tunable flag."); goto cleanup; } } else { ERR(sh, "Error attempting to create preserve_tunable flag."); goto cleanup; } } else { if (remove(path) == -1 && errno != ENOENT) { ERR(sh, "Error removing the preserve_tunables flag."); goto cleanup; } } /* Before we do anything else, flush the join to its component parts. * This *does not* flush to disk automatically */ if (users->dtable->is_modified(users->dbase)) { retval = users->dtable->flush(sh, users->dbase); if (retval < 0) goto cleanup; } /* Decide if anything was modified */ fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase); seusers_modified = seusers->dtable->is_modified(seusers->dbase); users_extra_modified = users_extra->dtable->is_modified(users_extra->dbase); ports_modified = ports->dtable->is_modified(ports->dbase); modified = sh->modules_modified; modified |= ports_modified; modified |= users->dtable->is_modified(users_base->dbase); modified |= bools->dtable->is_modified(bools->dbase); modified |= ifaces->dtable->is_modified(ifaces->dbase); modified |= nodes->dtable->is_modified(nodes->dbase); modified |= dontaudit_modified; modified |= preserve_tunables_modified; /* If there were policy changes, or explicitly requested, rebuild the policy */ if (sh->do_rebuild || modified) { /* =================== Module expansion =============== */ /* link all modules in the sandbox to the base module */ retval = semanage_get_modules_names(sh, &mod_filenames, &num_modfiles); if (retval < 0) goto cleanup; retval = semanage_verify_modules(sh, mod_filenames, num_modfiles); if (retval < 0) goto cleanup; retval = semanage_link_sandbox(sh, &base); if (retval < 0) goto cleanup; /* write the linked base if we want to save or we have a * verification program that wants it. */ linked_filename = semanage_path(SEMANAGE_TMP, SEMANAGE_LINKED); if (linked_filename == NULL) { retval = -1; goto cleanup; } if (sh->conf->save_linked || sh->conf->linked_prog) { retval = semanage_write_module(sh, linked_filename, base); if (retval < 0) goto cleanup; retval = semanage_verify_linked(sh); if (retval < 0) goto cleanup; /* remove the linked policy if we only wrote it for the * verification program. */ if (!sh->conf->save_linked) { retval = unlink(linked_filename); if (retval < 0) { ERR(sh, "could not remove linked base %s", linked_filename); goto cleanup; } } } else { /* Try to delete the linked copy - this is needed if * the save_link option has changed to prevent the * old linked copy from being copied forever. No error * checking is done because this is likely to fail because * the file does not exist - which is not an error. */ unlink(linked_filename); errno = 0; } /* ==================== File-backed ================== */ /* File Contexts */ /* Sort the file contexts. */ retval = semanage_fc_sort(sh, sepol_module_package_get_file_contexts(base), sepol_module_package_get_file_contexts_len(base), &sorted_fc_buffer, &sorted_fc_buffer_len); if (retval < 0) goto cleanup; /* Write the contexts (including template contexts) to a single file. * The buffer returned by the sort function has a trailing \0 character, * which we do NOT want to write out to disk, so we pass sorted_fc_buffer_len-1. */ ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL); if (ofilename == NULL) { retval = -1; goto cleanup; } retval = write_file(sh, ofilename, sorted_fc_buffer, sorted_fc_buffer_len - 1); if (retval < 0) goto cleanup; /* Split complete and template file contexts into their separate files. */ retval = semanage_split_fc(sh); if (retval < 0) goto cleanup; pfcontexts->dtable->drop_cache(pfcontexts->dbase); retval = semanage_direct_update_seuser(sh, base ); if (retval < 0) goto cleanup; retval = semanage_direct_update_user_extra(sh, base ); if (retval < 0) goto cleanup; /* Netfilter Contexts */ /* Sort the netfilter contexts. */ retval = semanage_nc_sort (sh, sepol_module_package_get_netfilter_contexts(base), sepol_module_package_get_netfilter_contexts_len(base), &sorted_nc_buffer, &sorted_nc_buffer_len); if (retval < 0) goto cleanup; /* Write the contexts to a single file. The buffer returned by * the sort function has a trailing \0 character, which we do * NOT want to write out to disk, so we pass sorted_fc_buffer_len-1. */ ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_NC); retval = write_file (sh, ofilename, sorted_nc_buffer, sorted_nc_buffer_len - 1); if (retval < 0) goto cleanup; /* ==================== Policydb-backed ================ */ /* Create new policy object, then attach to policy databases * that work with a policydb */ retval = semanage_expand_sandbox(sh, base, &out); if (retval < 0) goto cleanup; sepol_module_package_free(base); base = NULL; dbase_policydb_attach((dbase_policydb_t *) pusers_base->dbase, out); dbase_policydb_attach((dbase_policydb_t *) pports->dbase, out); dbase_policydb_attach((dbase_policydb_t *) pifaces->dbase, out); dbase_policydb_attach((dbase_policydb_t *) pbools->dbase, out); dbase_policydb_attach((dbase_policydb_t *) pnodes->dbase, out); /* ============= Apply changes, and verify =============== */ retval = semanage_base_merge_components(sh); if (retval < 0) goto cleanup; retval = semanage_write_policydb(sh, out); if (retval < 0) goto cleanup; retval = semanage_verify_kernel(sh); if (retval < 0) goto cleanup; } else { retval = sepol_policydb_create(&out); if (retval < 0) goto cleanup; retval = semanage_read_policydb(sh, out); if (retval < 0) goto cleanup; if (seusers_modified || users_extra_modified) { retval = semanage_link_base(sh, &base); if (retval < 0) goto cleanup; if (seusers_modified) { retval = semanage_direct_update_seuser(sh, base ); if (retval < 0) goto cleanup; } if (users_extra_modified) { /* Users_extra */ retval = semanage_direct_update_user_extra(sh, base ); if (retval < 0) goto cleanup; } sepol_module_package_free(base); base = NULL; } retval = semanage_base_merge_components(sh); if (retval < 0) goto cleanup; } /* ======= Post-process: Validate non-policydb components ===== */ /* Validate local modifications to file contexts. * Note: those are still cached, even though they've been * merged into the main file_contexts. We won't check the * large file_contexts - checked at compile time */ if (sh->do_rebuild || modified || fcontexts_modified) { retval = semanage_fcontext_validate_local(sh, out); if (retval < 0) goto cleanup; } /* Validate local seusers against policy */ if (sh->do_rebuild || modified || seusers_modified) { retval = semanage_seuser_validate_local(sh, out); if (retval < 0) goto cleanup; } /* Validate local ports for overlap */ if (sh->do_rebuild || ports_modified) { retval = semanage_port_validate_local(sh); if (retval < 0) goto cleanup; } /* ================== Write non-policydb components ========= */ /* Commit changes to components */ retval = semanage_commit_components(sh); if (retval < 0) goto cleanup; /* run genhomedircon if its enabled, this should be the last operation * which requires the out policydb */ if (!sh->conf->disable_genhomedircon) { if (out && (retval = semanage_genhomedircon(sh, out, sh->conf->usepasswd, sh->conf->ignoredirs)) != 0) { ERR(sh, "semanage_genhomedircon returned error code %d.", retval); goto cleanup; } } else { WARN(sh, "WARNING: genhomedircon is disabled. \ See /etc/selinux/semanage.conf if you need to enable it."); } /* free out, if we don't free it before calling semanage_install_sandbox * then fork() may fail on low memory machines */ sepol_policydb_free(out); out = NULL; if (sh->do_rebuild || modified || seusers_modified || fcontexts_modified || users_extra_modified) { retval = semanage_install_sandbox(sh); } cleanup: for (i = 0; mod_filenames != NULL && i < num_modfiles; i++) { free(mod_filenames[i]); } if (modified) { /* Detach from policydb, so it can be freed */ dbase_policydb_detach((dbase_policydb_t *) pusers_base->dbase); dbase_policydb_detach((dbase_policydb_t *) pports->dbase); dbase_policydb_detach((dbase_policydb_t *) pifaces->dbase); dbase_policydb_detach((dbase_policydb_t *) pnodes->dbase); dbase_policydb_detach((dbase_policydb_t *) pbools->dbase); } free(mod_filenames); sepol_policydb_free(out); semanage_release_trans_lock(sh); free(sorted_fc_buffer); free(sorted_nc_buffer); /* regardless if the commit was successful or not, remove the sandbox if it is still there */ semanage_remove_directory(semanage_path (SEMANAGE_TMP, SEMANAGE_TOPLEVEL)); return retval; } /* Writes a module to the sandbox's module directory, overwriting any * previous module stored within. Note that module data are not * free()d by this function; caller is responsible for deallocating it * if necessary. Returns 0 on success, -1 if out of memory, -2 if the * data does not represent a valid module file, -3 if error while * writing file. */ static int semanage_direct_install(semanage_handle_t * sh, char *data, size_t data_len) { int retval; char *module_name = NULL, *version = NULL, *filename = NULL; if ((retval = parse_module_headers(sh, data, data_len, &module_name, &version, &filename)) != 0) { goto cleanup; } if (bzip(sh, filename, data, data_len) <= 0) { ERR(sh, "Error while writing to %s.", filename); retval = -3; goto cleanup; } retval = 0; cleanup: free(version); free(filename); free(module_name); return retval; } /* Attempts to link a module to the sandbox's module directory, unlinking any * previous module stored within. Returns 0 on success, -1 if out of memory, -2 if the * data does not represent a valid module file, -3 if error while * writing file. */ static int semanage_direct_install_file(semanage_handle_t * sh, const char *install_filename) { int retval = -1; char *data = NULL; ssize_t data_len = 0; int compressed = 0; int in_fd = -1; if ((in_fd = open(install_filename, O_RDONLY)) == -1) { return -1; } if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) { goto cleanup; } if (compressed) { char *module_name = NULL, *version = NULL, *filename = NULL; if ((retval = parse_module_headers(sh, data, data_len, &module_name, &version, &filename)) != 0) { goto cleanup; } if (data_len > 0) munmap(data, data_len); data_len = 0; retval = dupfile(filename, in_fd); free(version); free(filename); free(module_name); } else { retval = semanage_direct_install(sh, data, data_len); } cleanup: close(in_fd); if (data_len > 0) munmap(data, data_len); return retval; } static int get_direct_upgrade_filename(semanage_handle_t * sh, char *data, size_t data_len, char **outfilename) { int i, retval, num_modules = 0; char *module_name = NULL, *version = NULL, *filename = NULL; semanage_module_info_t *modinfo = NULL; if ((retval = parse_module_headers(sh, data, data_len, &module_name, &version, &filename)) != 0) { goto cleanup; } if (semanage_direct_list(sh, &modinfo, &num_modules) < 0) { goto cleanup; } retval = -5; for (i = 0; i < num_modules; i++) { semanage_module_info_t *m = semanage_module_list_nth(modinfo, i); if (strcmp(semanage_module_get_name(m), module_name) == 0) { if (strverscmp(version, semanage_module_get_version(m)) > 0) { retval = 0; break; } else { ERR(sh, "Previous module %s is same or newer.", module_name); retval = -4; goto cleanup; } } } cleanup: free(version); free(module_name); for (i = 0; modinfo != NULL && i < num_modules; i++) { semanage_module_info_t *m = semanage_module_list_nth(modinfo, i); semanage_module_info_datum_destroy(m); } free(modinfo); if (retval == 0) { *outfilename = filename; } else { free(filename); } return retval; } /* Similar to semanage_direct_install(), except that it checks that * there already exists a module with the same name and that the * module is an older version then the one in 'data'. Returns 0 on * success, -1 if out of memory, -2 if the data does not represent a * valid module file, -3 if error while writing file or reading * modules directory, -4 if the previous module is same or newer than 'data', * -5 if there does not exist an older module. */ static int semanage_direct_upgrade(semanage_handle_t * sh, char *data, size_t data_len) { char *filename = NULL; int retval = get_direct_upgrade_filename(sh, data, data_len, &filename); if (retval == 0) { if (bzip(sh, filename, data, data_len) <= 0) { ERR(sh, "Error while writing to %s.", filename); retval = -3; } free(filename); } return retval; } /* Attempts to link a module to the sandbox's module directory, unlinking any * previous module stored within. * Returns 0 on success, -1 if out of memory, -2 if the * data does not represent a valid module file, -3 if error while * writing file. */ static int semanage_direct_upgrade_file(semanage_handle_t * sh, const char *module_filename) { int retval = -1; char *data = NULL; ssize_t data_len = 0; int compressed = 0; int in_fd = -1; if ((in_fd = open(module_filename, O_RDONLY)) == -1) { return -1; } if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) { goto cleanup; } if (compressed) { char *filename = NULL; retval = get_direct_upgrade_filename(sh, data, data_len, &filename); if (retval != 0) goto cleanup; retval = dupfile(filename, in_fd); free(filename); } else { retval = semanage_direct_upgrade(sh, data, data_len); } cleanup: close(in_fd); if (data_len > 0) munmap(data, data_len); return retval; } /* Writes a base module into a sandbox, overwriting any previous base * module. Note that 'module_data' is not free()d by this function; * caller is responsible for deallocating it if necessary. Returns 0 * on success, -1 if out of memory, -2 if the data does not represent * a valid base module file, -3 if error while writing file. */ static int semanage_direct_install_base(semanage_handle_t * sh, char *base_data, size_t data_len) { int retval = -1; const char *filename = NULL; if ((retval = parse_base_headers(sh, base_data, data_len)) != 0) { goto cleanup; } if ((filename = semanage_path(SEMANAGE_TMP, SEMANAGE_BASE)) == NULL) { goto cleanup; } if (bzip(sh, filename, base_data, data_len) <= 0) { ERR(sh, "Error while writing to %s.", filename); retval = -3; goto cleanup; } retval = 0; cleanup: return retval; } /* Writes a base module into a sandbox, overwriting any previous base * module. * Returns 0 on success, -1 if out of memory, -2 if the data does not represent * a valid base module file, -3 if error while writing file. */ static int semanage_direct_install_base_file(semanage_handle_t * sh, const char *install_filename) { int retval = -1; char *data = NULL; ssize_t data_len = 0; int compressed = 0; int in_fd; if ((in_fd = open(install_filename, O_RDONLY)) == -1) { return -1; } if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) { goto cleanup; } if (compressed) { const char *filename = NULL; if ((retval = parse_base_headers(sh, data, data_len)) != 0) { goto cleanup; } if ((filename = semanage_path(SEMANAGE_TMP, SEMANAGE_BASE)) == NULL) { goto cleanup; } retval = dupfile(filename, in_fd); } else { retval = semanage_direct_install_base(sh, data, data_len); } cleanup: close(in_fd); if (data_len > 0) munmap(data, data_len); return retval; } static int get_module_name(semanage_handle_t * sh, char *modulefile, char **module_name) { FILE *fp = NULL; int retval = -1; char *data = NULL; char *version = NULL; ssize_t size; int type; struct sepol_policy_file *pf = NULL; if (sepol_policy_file_create(&pf)) { ERR(sh, "Out of memory!"); goto cleanup; } sepol_policy_file_set_handle(pf, sh->sepolh); if ((fp = fopen(modulefile, "rb")) == NULL) { goto cleanup; } if ((size = bunzip(sh, fp, &data)) > 0) { sepol_policy_file_set_mem(pf, data, size); } else { rewind(fp); __fsetlocking(fp, FSETLOCKING_BYCALLER); sepol_policy_file_set_fp(pf, fp); } retval = sepol_module_package_info(pf, &type, module_name, &version); cleanup: sepol_policy_file_free(pf); if (fp) fclose(fp); free(data); free(version); return retval; } static int get_module_file_by_name(semanage_handle_t * sh, const char *module_name, char **module_file) { int i, retval = -1; char **module_filenames = NULL; char *name = NULL; int num_mod_files; if (semanage_get_modules_names(sh, &module_filenames, &num_mod_files) == -1) { return -1; } for (i = 0; i < num_mod_files; i++) { int rc = get_module_name(sh, module_filenames[i], &name); if (rc < 0) continue; if (strcmp(module_name, name) == 0) { *module_file = strdup(module_filenames[i]); if (*module_file) retval = 0; goto cleanup; } free(name); name = NULL; } ERR(sh, "Module %s was not found.", module_name); retval = -2; /* module not found */ cleanup: free(name); for (i = 0; module_filenames != NULL && i < num_mod_files; i++) { free(module_filenames[i]); } free(module_filenames); return retval; } /* Enables a module from the sandbox. Returns 0 on success, -1 if out * of memory, -2 if module not found or could not be enabled. */ static int semanage_direct_enable(semanage_handle_t * sh, char *module_name) { char *module_filename = NULL; int retval = get_module_file_by_name(sh, module_name, &module_filename); if (retval < 0) return -1; /* module not found */ retval = semanage_enable_module(module_filename); if (retval < 0) { ERR(sh, "Could not enable module file %s.", module_filename); retval = -2; } free(module_filename); return retval; } /* Disables a module from the sandbox. Returns 0 on success, -1 if out * of memory, -2 if module not found or could not be enabled. */ static int semanage_direct_disable(semanage_handle_t * sh, char *module_name) { char *module_filename = NULL; int retval = get_module_file_by_name(sh, module_name, &module_filename); if (retval < 0) return -1; /* module not found */ retval = semanage_disable_module(module_filename); if (retval < 0) { ERR(sh, "Could not disable module file %s.", module_filename); retval = -2; } free(module_filename); return retval; } /* Removes a module from the sandbox. Returns 0 on success, -1 if out * of memory, -2 if module not found or could not be removed. */ static int semanage_direct_remove(semanage_handle_t * sh, char *module_name) { char *module_filename = NULL; int retval = get_module_file_by_name(sh, module_name, &module_filename); if (retval < 0) return -1; /* module not found */ (void) semanage_enable_module(module_filename); /* Don't care if this fails */ retval = unlink(module_filename); if (retval < 0) { ERR(sh, "Could not remove module file %s.", module_filename); retval = -2; } free(module_filename); return retval; } /* Allocate an array of module_info structures for each readable * module within the store. Note that if the calling program has * already begun a transaction then this function will get a list of * modules within the sandbox. The caller is responsible for calling * semanage_module_info_datum_destroy() on each element of the array * as well as free()ing the entire list. */ static int semanage_direct_list(semanage_handle_t * sh, semanage_module_info_t ** modinfo, int *num_modules) { struct sepol_policy_file *pf = NULL; int i, retval = -1; char **module_filenames = NULL; int num_mod_files; *modinfo = NULL; *num_modules = 0; /* get the read lock when reading from the active (non-transaction) directory */ if (!sh->is_in_transaction) if (semanage_get_active_lock(sh) < 0) return -1; if (semanage_get_modules_names(sh, &module_filenames, &num_mod_files) == -1) { goto cleanup; } if (num_mod_files == 0) { retval = semanage_direct_get_serial(sh); goto cleanup; } if (sepol_policy_file_create(&pf)) { ERR(sh, "Out of memory!"); goto cleanup; } sepol_policy_file_set_handle(pf, sh->sepolh); if ((*modinfo = calloc(num_mod_files, sizeof(**modinfo))) == NULL) { ERR(sh, "Out of memory!"); goto cleanup; } for (i = 0; i < num_mod_files; i++) { FILE *fp; char *name = NULL, *version = NULL; int type; if ((fp = fopen(module_filenames[i], "rb")) == NULL) { /* could not open this module file, so don't * report it */ continue; } ssize_t size; char *data = NULL; int enabled = semanage_module_enabled(module_filenames[i]); if ((size = bunzip(sh, fp, &data)) > 0) { sepol_policy_file_set_mem(pf, data, size); } else { rewind(fp); __fsetlocking(fp, FSETLOCKING_BYCALLER); sepol_policy_file_set_fp(pf, fp); } if (sepol_module_package_info(pf, &type, &name, &version)) { fclose(fp); free(data); free(name); free(version); continue; } fclose(fp); free(data); if (type == SEPOL_POLICY_MOD) { (*modinfo)[*num_modules].name = name; (*modinfo)[*num_modules].version = version; (*modinfo)[*num_modules].enabled = enabled; (*num_modules)++; } else { /* file was not a module, so don't report it */ free(name); free(version); } } retval = semanage_direct_get_serial(sh); cleanup: sepol_policy_file_free(pf); for (i = 0; module_filenames != NULL && i < num_mod_files; i++) { free(module_filenames[i]); } free(module_filenames); if (!sh->is_in_transaction) { semanage_release_active_lock(sh); } return retval; } int semanage_direct_access_check(semanage_handle_t * sh) { char polpath[PATH_MAX]; snprintf(polpath, PATH_MAX, "%s%s", semanage_selinux_path(), sh->conf->store_path); if (semanage_check_init(polpath)) return -1; return semanage_store_access_check(); } int semanage_direct_mls_enabled(semanage_handle_t * sh) { sepol_policydb_t *p = NULL; int retval; retval = sepol_policydb_create(&p); if (retval < 0) goto cleanup; retval = semanage_read_policydb(sh, p); if (retval < 0) goto cleanup; retval = sepol_policydb_mls_enabled(p); cleanup: sepol_policydb_free(p); return retval; } libsemanage-2.3/src/direct_api.h000066400000000000000000000026621233221606300166740ustar00rootroot00000000000000/* Authors: Jason Tang * * Copyright (C) 2004-2005 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SEMANAGE_DIRECT_API_H_ #define _SEMANAGE_DIRECT_API_H_ /* Circular dependency */ struct semanage_handle; /* Direct component of handle */ struct semanage_direct_handle { /* Locking */ int activelock_file_fd; int translock_file_fd; }; int semanage_direct_connect(struct semanage_handle *sh); int semanage_direct_is_managed(struct semanage_handle *sh); int semanage_direct_access_check(struct semanage_handle *sh); int semanage_direct_mls_enabled(struct semanage_handle *sh); #include #include ssize_t bunzip(struct semanage_handle *sh, FILE *f, char **data); #endif libsemanage-2.3/src/dso.h000066400000000000000000000012041233221606300153450ustar00rootroot00000000000000#ifndef _SEPOL_DSO_H #define _SEPOL_DSO_H 1 #ifdef SHARED # define hidden __attribute__ ((visibility ("hidden"))) # define hidden_proto(fct) __hidden_proto (fct, fct##_internal) # define __hidden_proto(fct, internal) \ extern __typeof (fct) internal; \ extern __typeof (fct) fct __asm (#internal) hidden; # if defined(__alpha__) || defined(__mips__) # define hidden_def(fct) \ asm (".globl " #fct "\n" #fct " = " #fct "_internal"); # else # define hidden_def(fct) \ asm (".globl " #fct "\n.set " #fct ", " #fct "_internal"); #endif #else # define hidden # define hidden_proto(fct) # define hidden_def(fct) #endif #endif libsemanage-2.3/src/exception.sh000066400000000000000000000004741233221606300167510ustar00rootroot00000000000000function except() { echo " %exception $1 { \$action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } } " } gcc -x c -c -I../include - -aux-info temp.aux < ../include/semanage/semanage.h for i in `awk '/extern int/ { print $6 }' temp.aux`; do except $i ; done rm -f -- temp.aux -.o libsemanage-2.3/src/fcontext_internal.h000066400000000000000000000026151233221606300203150ustar00rootroot00000000000000#ifndef _SEMANAGE_FCONTEXT_INTERNAL_H_ #define _SEMANAGE_FCONTEXT_INTERNAL_H_ #include #include #include #include #include "database.h" #include "handle.h" #include "dso.h" hidden_proto(semanage_fcontext_key_create) hidden_proto(semanage_fcontext_key_extract) hidden_proto(semanage_fcontext_key_free) hidden_proto(semanage_fcontext_compare) hidden_proto(semanage_fcontext_compare2) hidden_proto(semanage_fcontext_create) hidden_proto(semanage_fcontext_get_expr) hidden_proto(semanage_fcontext_set_expr) hidden_proto(semanage_fcontext_get_type) hidden_proto(semanage_fcontext_get_type_str) hidden_proto(semanage_fcontext_set_type) hidden_proto(semanage_fcontext_get_con) hidden_proto(semanage_fcontext_set_con) hidden_proto(semanage_fcontext_clone) hidden_proto(semanage_fcontext_free) hidden_proto(semanage_fcontext_iterate_local) /* FCONTEXT RECORD: metod table */ extern record_table_t SEMANAGE_FCONTEXT_RTABLE; extern int fcontext_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig); extern void fcontext_file_dbase_release(dbase_config_t * dconfig); extern int hidden semanage_fcontext_validate_local(semanage_handle_t * handle, const sepol_policydb_t * policydb); #endif libsemanage-2.3/src/fcontext_record.c000066400000000000000000000151301233221606300177460ustar00rootroot00000000000000struct semanage_fcontext; struct semanage_fcontext_key; typedef struct semanage_fcontext record_t; typedef struct semanage_fcontext_key record_key_t; #define DBASE_RECORD_DEFINED #include #include #include "fcontext_internal.h" #include "context_internal.h" #include "debug.h" struct semanage_fcontext { /* Matching expression */ char *expr; /* Type of object */ int type; /* Context */ semanage_context_t *con; }; struct semanage_fcontext_key { /* Matching expression */ char *expr; /* Type of object */ int type; }; /* Key */ int semanage_fcontext_key_create(semanage_handle_t * handle, const char *expr, int type, semanage_fcontext_key_t ** key_ptr) { semanage_fcontext_key_t *tmp_key = (semanage_fcontext_key_t *) malloc(sizeof(semanage_fcontext_key_t)); if (!tmp_key) { ERR(handle, "out of memory, could not " "create file context key"); return STATUS_ERR; } tmp_key->expr = strdup(expr); if (!tmp_key->expr) { ERR(handle, "out of memory, could not create file context key."); free(tmp_key); return STATUS_ERR; } tmp_key->type = type; *key_ptr = tmp_key; return STATUS_SUCCESS; } hidden_def(semanage_fcontext_key_create) int semanage_fcontext_key_extract(semanage_handle_t * handle, const semanage_fcontext_t * fcontext, semanage_fcontext_key_t ** key_ptr) { if (semanage_fcontext_key_create(handle, fcontext->expr, fcontext->type, key_ptr) < 0) { ERR(handle, "could not extract key from " "file context %s (%s)", fcontext->expr, semanage_fcontext_get_type_str(fcontext->type)); return STATUS_ERR; } return STATUS_SUCCESS; } hidden_def(semanage_fcontext_key_extract) void semanage_fcontext_key_free(semanage_fcontext_key_t * key) { free(key->expr); free(key); } hidden_def(semanage_fcontext_key_free) int semanage_fcontext_compare(const semanage_fcontext_t * fcontext, const semanage_fcontext_key_t * key) { int rv = strcmp(fcontext->expr, key->expr); if (rv != 0) return rv; else { if (fcontext->type < key->type) return -1; else if (key->type < fcontext->type) return 1; else return 0; } } hidden_def(semanage_fcontext_compare) int semanage_fcontext_compare2(const semanage_fcontext_t * fcontext, const semanage_fcontext_t * fcontext2) { int rv = strcmp(fcontext->expr, fcontext2->expr); if (rv != 0) return rv; else { if (fcontext->type < fcontext2->type) return -1; else if (fcontext2->type < fcontext->type) return 1; else return 0; } } hidden_def(semanage_fcontext_compare2) static int semanage_fcontext_compare2_qsort(const semanage_fcontext_t ** fcontext, const semanage_fcontext_t ** fcontext2) { return semanage_fcontext_compare2(*fcontext, *fcontext2); } /* Create */ int semanage_fcontext_create(semanage_handle_t * handle, semanage_fcontext_t ** fcontext) { semanage_fcontext_t *tmp_fcontext = (semanage_fcontext_t *) malloc(sizeof(semanage_fcontext_t)); if (!tmp_fcontext) { ERR(handle, "out of memory, could not create " "file context record"); return STATUS_ERR; } tmp_fcontext->expr = NULL; tmp_fcontext->type = SEMANAGE_FCONTEXT_ALL; tmp_fcontext->con = NULL; *fcontext = tmp_fcontext; return STATUS_SUCCESS; } hidden_def(semanage_fcontext_create) /* Regexp */ const char *semanage_fcontext_get_expr(const semanage_fcontext_t * fcontext) { return fcontext->expr; } hidden_def(semanage_fcontext_get_expr) int semanage_fcontext_set_expr(semanage_handle_t * handle, semanage_fcontext_t * fcontext, const char *expr) { char *tmp_expr = strdup(expr); if (!tmp_expr) { ERR(handle, "out of memory, " "could not set regexp string"); return STATUS_ERR; } free(fcontext->expr); fcontext->expr = tmp_expr; return STATUS_SUCCESS; } hidden_def(semanage_fcontext_set_expr) /* Type */ int semanage_fcontext_get_type(const semanage_fcontext_t * fcontext) { return fcontext->type; } hidden_def(semanage_fcontext_get_type) const char *semanage_fcontext_get_type_str(int type) { switch (type) { case SEMANAGE_FCONTEXT_ALL: return "all files"; case SEMANAGE_FCONTEXT_REG: return "regular file"; case SEMANAGE_FCONTEXT_DIR: return "directory"; case SEMANAGE_FCONTEXT_CHAR: return "character device"; case SEMANAGE_FCONTEXT_BLOCK: return "block device"; case SEMANAGE_FCONTEXT_SOCK: return "socket"; case SEMANAGE_FCONTEXT_LINK: return "symbolic link"; case SEMANAGE_FCONTEXT_PIPE: return "named pipe"; default: return "????"; } } hidden_def(semanage_fcontext_get_type_str) void semanage_fcontext_set_type(semanage_fcontext_t * fcontext, int type) { fcontext->type = type; } hidden_def(semanage_fcontext_set_type) /* Context */ semanage_context_t *semanage_fcontext_get_con(const semanage_fcontext_t * fcontext) { return fcontext->con; } hidden_def(semanage_fcontext_get_con) int semanage_fcontext_set_con(semanage_handle_t * handle, semanage_fcontext_t * fcontext, semanage_context_t * con) { semanage_context_t *newcon; if (semanage_context_clone(handle, con, &newcon) < 0) { ERR(handle, "out of memory, could not set file context"); return STATUS_ERR; } semanage_context_free(fcontext->con); fcontext->con = newcon; return STATUS_SUCCESS; } hidden_def(semanage_fcontext_set_con) /* Deep copy clone */ int semanage_fcontext_clone(semanage_handle_t * handle, const semanage_fcontext_t * fcontext, semanage_fcontext_t ** fcontext_ptr) { semanage_fcontext_t *new_fcontext = NULL; if (semanage_fcontext_create(handle, &new_fcontext) < 0) goto err; if (semanage_fcontext_set_expr(handle, new_fcontext, fcontext->expr) < 0) goto err; new_fcontext->type = fcontext->type; if (fcontext->con && (semanage_context_clone(handle, fcontext->con, &new_fcontext->con) < 0)) goto err; *fcontext_ptr = new_fcontext; return STATUS_SUCCESS; err: ERR(handle, "could not clone file context record"); semanage_fcontext_free(new_fcontext); return STATUS_ERR; } hidden_def(semanage_fcontext_clone) /* Destroy */ void semanage_fcontext_free(semanage_fcontext_t * fcontext) { if (!fcontext) return; free(fcontext->expr); semanage_context_free(fcontext->con); free(fcontext); } hidden_def(semanage_fcontext_free) /* Record base functions */ record_table_t SEMANAGE_FCONTEXT_RTABLE = { .create = semanage_fcontext_create, .key_extract = semanage_fcontext_key_extract, .key_free = semanage_fcontext_key_free, .clone = semanage_fcontext_clone, .compare = semanage_fcontext_compare, .compare2 = semanage_fcontext_compare2, .compare2_qsort = semanage_fcontext_compare2_qsort, .free = semanage_fcontext_free, }; libsemanage-2.3/src/fcontexts_file.c000066400000000000000000000106551233221606300176010ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_fcontext; struct semanage_fcontext_key; typedef struct semanage_fcontext record_t; typedef struct semanage_fcontext_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_file; typedef struct dbase_file dbase_t; #define DBASE_DEFINED #include #include #include #include #include "fcontext_internal.h" #include "context_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" static const char *type_str(int type) { switch (type) { default: case SEMANAGE_FCONTEXT_ALL: return " "; case SEMANAGE_FCONTEXT_REG: return "--"; case SEMANAGE_FCONTEXT_DIR: return "-d"; case SEMANAGE_FCONTEXT_CHAR: return "-c"; case SEMANAGE_FCONTEXT_BLOCK: return "-b"; case SEMANAGE_FCONTEXT_SOCK: return "-s"; case SEMANAGE_FCONTEXT_LINK: return "-l"; case SEMANAGE_FCONTEXT_PIPE: return "-p"; } } static int fcontext_print(semanage_handle_t * handle, semanage_fcontext_t * fcontext, FILE * str) { char *con_str = NULL; const char *expr = semanage_fcontext_get_expr(fcontext); int type = semanage_fcontext_get_type(fcontext); const char *print_str = type_str(type); const char *tstr = semanage_fcontext_get_type_str(type); semanage_context_t *con = semanage_fcontext_get_con(fcontext); if (fprintf(str, "%s %s ", expr, print_str) < 0) goto err; if (con != NULL) { if (semanage_context_to_string(handle, con, &con_str) < 0) goto err; if (fprintf(str, "%s\n", con_str) < 0) goto err; free(con_str); con_str = NULL; } else { if (fprintf(str, "<>\n") < 0) goto err; } return STATUS_SUCCESS; err: ERR(handle, "could not print file context for " "%s (%s) to stream", expr, tstr); free(con_str); return STATUS_ERR; } static int fcontext_parse(semanage_handle_t * handle, parse_info_t * info, semanage_fcontext_t * fcontext) { char *str = NULL; semanage_context_t *con = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (!info->ptr) goto last; /* Regexp */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_fcontext_set_expr(handle, fcontext, str) < 0) goto err; free(str); str = NULL; /* Type */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (!strcasecmp(str, "-s")) semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_SOCK); else if (!strcasecmp(str, "-p")) semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_PIPE); else if (!strcasecmp(str, "-b")) semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_BLOCK); else if (!strcasecmp(str, "-l")) semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_LINK); else if (!strcasecmp(str, "-c")) semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_CHAR); else if (!strcasecmp(str, "-d")) semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_DIR); else if (!strcasecmp(str, "--")) semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_REG); else goto process_context; free(str); str = NULL; /* Context */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; process_context: if (semanage_context_from_string(handle, str, &con) < 0) { ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s", str, info->filename, info->lineno, info->orig_line); goto err; } free(str); str = NULL; if (con && semanage_fcontext_set_con(handle, fcontext, con) < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; semanage_context_free(con); return STATUS_SUCCESS; last: parse_dispose_line(info); return STATUS_NODATA; err: ERR(handle, "could not parse file context record"); free(str); semanage_context_free(con); parse_dispose_line(info); return STATUS_ERR; } /* FCONTEXT RECORD: FILE extension: method table */ record_file_table_t SEMANAGE_FCONTEXT_FILE_RTABLE = { .parse = fcontext_parse, .print = fcontext_print, }; int fcontext_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig) { if (dbase_file_init(handle, fname, &SEMANAGE_FCONTEXT_RTABLE, &SEMANAGE_FCONTEXT_FILE_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_FILE_DTABLE; return STATUS_SUCCESS; } void fcontext_file_dbase_release(dbase_config_t * dconfig) { dbase_file_release(dconfig->dbase); } libsemanage-2.3/src/fcontexts_local.c000066400000000000000000000067231233221606300177550ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_fcontext; struct semanage_fcontext_key; typedef struct semanage_fcontext_key record_key_t; typedef struct semanage_fcontext record_t; #define DBASE_RECORD_DEFINED #include #include #include #include "fcontext_internal.h" #include "context_internal.h" #include "debug.h" #include "handle.h" #include "database.h" int semanage_fcontext_modify_local(semanage_handle_t * handle, const semanage_fcontext_key_t * key, const semanage_fcontext_t * data) { dbase_config_t *dconfig = semanage_fcontext_dbase_local(handle); return dbase_modify(handle, dconfig, key, data); } int semanage_fcontext_del_local(semanage_handle_t * handle, const semanage_fcontext_key_t * key) { dbase_config_t *dconfig = semanage_fcontext_dbase_local(handle); return dbase_del(handle, dconfig, key); } int semanage_fcontext_query_local(semanage_handle_t * handle, const semanage_fcontext_key_t * key, semanage_fcontext_t ** response) { dbase_config_t *dconfig = semanage_fcontext_dbase_local(handle); return dbase_query(handle, dconfig, key, response); } int semanage_fcontext_exists_local(semanage_handle_t * handle, const semanage_fcontext_key_t * key, int *response) { dbase_config_t *dconfig = semanage_fcontext_dbase_local(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_fcontext_count_local(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_fcontext_dbase_local(handle); return dbase_count(handle, dconfig, response); } int semanage_fcontext_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_fcontext_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_fcontext_dbase_local(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } hidden_def(semanage_fcontext_iterate_local) int semanage_fcontext_list_local(semanage_handle_t * handle, semanage_fcontext_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_fcontext_dbase_local(handle); return dbase_list(handle, dconfig, records, count); } struct validate_handler_arg { semanage_handle_t *handle; const sepol_policydb_t *policydb; }; static int validate_handler(const semanage_fcontext_t * fcon, void *varg) { char *str; /* Unpack varg */ struct validate_handler_arg *arg = (struct validate_handler_arg *)varg; semanage_handle_t *handle = arg->handle; const sepol_policydb_t *policydb = arg->policydb; /* Unpack fcontext */ const char *expr = semanage_fcontext_get_expr(fcon); int type = semanage_fcontext_get_type(fcon); const char *type_str = semanage_fcontext_get_type_str(type); semanage_context_t *con = semanage_fcontext_get_con(fcon); if (con && sepol_context_check(handle->sepolh, policydb, (sepol_context_t *) con) < 0) goto invalid; return 0; invalid: if (semanage_context_to_string(handle, con, &str) >= 0) { ERR(handle, "invalid context %s specified for %s [%s]", str, expr, type_str); free(str); } else ERR(handle, "invalid context specified for %s [%s]", expr, type_str); return -1; } int hidden semanage_fcontext_validate_local(semanage_handle_t * handle, const sepol_policydb_t * policydb) { struct validate_handler_arg arg; arg.handle = handle; arg.policydb = policydb; return semanage_fcontext_iterate_local(handle, validate_handler, &arg); } libsemanage-2.3/src/fcontexts_policy.c000066400000000000000000000030171233221606300201530ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_fcontext; struct semanage_fcontext_key; typedef struct semanage_fcontext_key record_key_t; typedef struct semanage_fcontext record_t; #define DBASE_RECORD_DEFINED #include "fcontext_internal.h" #include "handle.h" #include "database.h" int semanage_fcontext_query(semanage_handle_t * handle, const semanage_fcontext_key_t * key, semanage_fcontext_t ** response) { dbase_config_t *dconfig = semanage_fcontext_dbase_policy(handle); return dbase_query(handle, dconfig, key, response); } int semanage_fcontext_exists(semanage_handle_t * handle, const semanage_fcontext_key_t * key, int *response) { dbase_config_t *dconfig = semanage_fcontext_dbase_policy(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_fcontext_count(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_fcontext_dbase_policy(handle); return dbase_count(handle, dconfig, response); } int semanage_fcontext_iterate(semanage_handle_t * handle, int (*handler) (const semanage_fcontext_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_fcontext_dbase_policy(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_fcontext_list(semanage_handle_t * handle, semanage_fcontext_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_fcontext_dbase_policy(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-2.3/src/genhomedircon.c000066400000000000000000000645051233221606300174110ustar00rootroot00000000000000/* Author: Mark Goldman * Paul Rosenfeld * Todd C. Miller * * Copyright (C) 2007 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA */ #include #include #include #include #include #include #include #include #include "semanage_store.h" #include "seuser_internal.h" #include "debug.h" #include "utilities.h" #include "genhomedircon.h" #include #include #include #include #include #include #include #include #include #include #include #include #include /* paths used in get_home_dirs() */ #define PATH_ETC_USERADD "/etc/default/useradd" #define PATH_ETC_LIBUSER "/etc/libuser.conf" #define PATH_DEFAULT_HOME "/home" #define PATH_EXPORT_HOME "/export/home" #define PATH_ETC_LOGIN_DEFS "/etc/login.defs" /* other paths */ #define PATH_SHELLS_FILE "/etc/shells" #define PATH_NOLOGIN_SHELL "/sbin/nologin" /* comments written to context file */ #define COMMENT_FILE_CONTEXT_HEADER "#\n#\n# " \ "User-specific file contexts, generated via libsemanage\n" \ "# use semanage command to manage system users to change" \ " the file_context\n#\n#\n" #define COMMENT_USER_HOME_CONTEXT "\n\n#\n# Home Context for user %s" \ "\n#\n\n" /* placeholders used in the template file which are searched for and replaced */ #define TEMPLATE_HOME_ROOT "HOME_ROOT" #define TEMPLATE_HOME_DIR "HOME_DIR" #define TEMPLATE_USER "USER" #define TEMPLATE_ROLE "ROLE" #define TEMPLATE_SEUSER "system_u" #define TEMPLATE_LEVEL "s0" #define FALLBACK_USER "user_u" #define FALLBACK_USER_PREFIX "user" #define FALLBACK_USER_LEVEL "s0" #define DEFAULT_LOGIN "__default__" typedef struct { const char *fcfilepath; int usepasswd; const char *homedir_template_path; char *fallback_user; char *fallback_user_prefix; char *fallback_user_level; semanage_handle_t *h_semanage; sepol_policydb_t *policydb; } genhomedircon_settings_t; typedef struct user_entry { char *name; char *sename; char *prefix; char *home; char *level; struct user_entry *next; } genhomedircon_user_entry_t; typedef struct { const char *search_for; const char *replace_with; } replacement_pair_t; typedef struct { const char *dir; int matched; } fc_match_handle_t; typedef struct IgnoreDir { struct IgnoreDir *next; char *dir; } ignoredir_t; ignoredir_t *ignore_head = NULL; static void ignore_free(void) { ignoredir_t *next; while (ignore_head) { next = ignore_head->next; free(ignore_head->dir); free(ignore_head); ignore_head = next; } } static int ignore_setup(char *ignoredirs) { char *tok; ignoredir_t *ptr = NULL; tok = strtok(ignoredirs, ";"); while(tok) { ptr = calloc(sizeof(ignoredir_t),1); if (!ptr) goto err; ptr->dir = strdup(tok); if (!ptr->dir) goto err; ptr->next = ignore_head; ignore_head = ptr; tok = strtok(NULL, ";"); } return 0; err: free(ptr); ignore_free(); return -1; } static int ignore(const char *homedir) { ignoredir_t *ptr = ignore_head; while (ptr) { if (strcmp(ptr->dir, homedir) == 0) { return 1; } ptr = ptr->next; } return 0; } static semanage_list_t *default_shell_list(void) { semanage_list_t *list = NULL; if (semanage_list_push(&list, "/bin/csh") || semanage_list_push(&list, "/bin/tcsh") || semanage_list_push(&list, "/bin/ksh") || semanage_list_push(&list, "/bin/bsh") || semanage_list_push(&list, "/bin/ash") || semanage_list_push(&list, "/usr/bin/ksh") || semanage_list_push(&list, "/usr/bin/pdksh") || semanage_list_push(&list, "/bin/zsh") || semanage_list_push(&list, "/bin/sh") || semanage_list_push(&list, "/bin/bash")) goto fail; return list; fail: semanage_list_destroy(&list); return NULL; } static semanage_list_t *get_shell_list(void) { FILE *shells; char *temp = NULL; semanage_list_t *list = NULL; size_t buff_len = 0; ssize_t len; shells = fopen(PATH_SHELLS_FILE, "r"); if (!shells) return default_shell_list(); while ((len = getline(&temp, &buff_len, shells)) > 0) { if (temp[len-1] == '\n') temp[len-1] = 0; if (strcmp(temp, PATH_NOLOGIN_SHELL)) { if (semanage_list_push(&list, temp)) { free(temp); semanage_list_destroy(&list); return default_shell_list(); } } } free(temp); return list; } /* Helper function called via semanage_fcontext_iterate() */ static int fcontext_matches(const semanage_fcontext_t *fcontext, void *varg) { const char *oexpr = semanage_fcontext_get_expr(fcontext); fc_match_handle_t *handp = varg; struct Ustr *expr; regex_t re; int type, retval = -1; /* Only match ALL or DIR */ type = semanage_fcontext_get_type(fcontext); if (type != SEMANAGE_FCONTEXT_ALL && type != SEMANAGE_FCONTEXT_ALL) return 0; /* Convert oexpr into a Ustr and anchor it at the beginning */ expr = ustr_dup_cstr("^"); if (expr == USTR_NULL) goto done; if (!ustr_add_cstr(&expr, oexpr)) goto done; /* Strip off trailing ".+" or ".*" */ if (ustr_cmp_suffix_cstr_eq(expr, ".+") || ustr_cmp_suffix_cstr_eq(expr, ".*")) { if (!ustr_del(&expr, 2)) goto done; } /* Strip off trailing "(/.*)?" */ if (ustr_cmp_suffix_cstr_eq(expr, "(/.*)?")) { if (!ustr_del(&expr, 6)) goto done; } if (ustr_cmp_suffix_cstr_eq(expr, "/")) { if (!ustr_del(&expr, 1)) goto done; } /* Append pattern to eat up trailing slashes */ if (!ustr_add_cstr(&expr, "/*$")) goto done; /* Check dir against expr */ if (regcomp(&re, ustr_cstr(expr), REG_EXTENDED) != 0) goto done; if (regexec(&re, handp->dir, 0, NULL, 0) == 0) handp->matched = 1; regfree(&re); retval = 0; done: ustr_free(expr); return retval; } static semanage_list_t *get_home_dirs(genhomedircon_settings_t * s) { semanage_list_t *homedir_list = NULL; semanage_list_t *shells = NULL; fc_match_handle_t hand; char *rbuf = NULL; char *path = NULL; long rbuflen; uid_t temp, minuid = 500, maxuid = 60000; int minuid_set = 0; struct passwd pwstorage, *pwbuf; struct stat buf; int retval; path = semanage_findval(PATH_ETC_USERADD, "HOME", "="); if (path && *path) { if (semanage_list_push(&homedir_list, path)) goto fail; } free(path); path = semanage_findval(PATH_ETC_LIBUSER, "LU_HOMEDIRECTORY", "="); if (path && *path) { if (semanage_list_push(&homedir_list, path)) goto fail; } free(path); path = NULL; if (!homedir_list) { if (semanage_list_push(&homedir_list, PATH_DEFAULT_HOME)) { goto fail; } } if (!stat(PATH_EXPORT_HOME, &buf)) { if (S_ISDIR(buf.st_mode)) { if (semanage_list_push(&homedir_list, PATH_EXPORT_HOME)) { goto fail; } } } if (!(s->usepasswd)) return homedir_list; shells = get_shell_list(); assert(shells); path = semanage_findval(PATH_ETC_LOGIN_DEFS, "UID_MIN", NULL); if (path && *path) { temp = atoi(path); minuid = temp; minuid_set = 1; } free(path); path = NULL; path = semanage_findval(PATH_ETC_LOGIN_DEFS, "UID_MAX", NULL); if (path && *path) { temp = atoi(path); maxuid = temp; } free(path); path = NULL; path = semanage_findval(PATH_ETC_LIBUSER, "LU_UIDNUMBER", "="); if (path && *path) { temp = atoi(path); if (!minuid_set || temp < minuid) { minuid = temp; minuid_set = 1; } } free(path); path = NULL; rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); if (rbuflen <= 0) goto fail; rbuf = malloc(rbuflen); if (rbuf == NULL) goto fail; setpwent(); while ((retval = getpwent_r(&pwstorage, rbuf, rbuflen, &pwbuf)) == 0) { if (pwbuf->pw_uid < minuid || pwbuf->pw_uid > maxuid) continue; if (!semanage_list_find(shells, pwbuf->pw_shell)) continue; int len = strlen(pwbuf->pw_dir) -1; for(; len > 0 && pwbuf->pw_dir[len] == '/'; len--) { pwbuf->pw_dir[len] = '\0'; } if (strcmp(pwbuf->pw_dir, "/") == 0) continue; if (ignore(pwbuf->pw_dir)) continue; if (semanage_str_count(pwbuf->pw_dir, '/') <= 1) continue; if (!(path = strdup(pwbuf->pw_dir))) { break; } semanage_rtrim(path, '/'); if (!semanage_list_find(homedir_list, path)) { /* * Now check for an existing file context that matches * so we don't label a non-homedir as a homedir. */ hand.dir = path; hand.matched = 0; if (semanage_fcontext_iterate(s->h_semanage, fcontext_matches, &hand) == STATUS_ERR) goto fail; /* NOTE: old genhomedircon printed a warning on match */ if (hand.matched) { WARN(s->h_semanage, "%s homedir %s or its parent directory conflicts with a file context already specified in the policy. This usually indicates an incorrectly defined system account. If it is a system account please make sure its uid is less than %u or greater than %u or its login shell is /sbin/nologin.", pwbuf->pw_name, pwbuf->pw_dir, minuid, maxuid); } else { if (semanage_list_push(&homedir_list, path)) goto fail; } } free(path); path = NULL; } if (retval && retval != ENOENT) { WARN(s->h_semanage, "Error while fetching users. " "Returning list so far."); } if (semanage_list_sort(&homedir_list)) goto fail; endpwent(); free(rbuf); semanage_list_destroy(&shells); return homedir_list; fail: endpwent(); free(rbuf); free(path); semanage_list_destroy(&homedir_list); semanage_list_destroy(&shells); return NULL; } /** * @param out the FILE to put all the output in. * @return 0 on success */ static int write_file_context_header(FILE * out) { if (fprintf(out, COMMENT_FILE_CONTEXT_HEADER) < 0) { return STATUS_ERR; } return STATUS_SUCCESS; } /* Predicates for use with semanage_slurp_file_filter() the homedir_template * file currently contains lines that serve as the template for a user's * homedir. * * It also contains lines that are the template for the parent of a * user's home directory. * * Currently, the only lines that apply to the the root of a user's home * directory are all prefixed with the string "HOME_ROOT". All other * lines apply to a user's home directory. If this changes the * following predicates need to change to reflect that. */ static int HOME_ROOT_PRED(const char *string) { return semanage_is_prefix(string, TEMPLATE_HOME_ROOT); } static int HOME_DIR_PRED(const char *string) { return semanage_is_prefix(string, TEMPLATE_HOME_DIR); } static int USER_CONTEXT_PRED(const char *string) { return (int)(strstr(string, TEMPLATE_USER) != NULL); } /* make_tempate * @param s the settings holding the paths to various files * @param pred function pointer to function to use as filter for slurp * file filter * @return a list of lines from the template file with inappropriate * lines filtered out. */ static semanage_list_t *make_template(genhomedircon_settings_t * s, int (*pred) (const char *)) { FILE *template_file = NULL; semanage_list_t *template_data = NULL; template_file = fopen(s->homedir_template_path, "r"); if (!template_file) return NULL; template_data = semanage_slurp_file_filter(template_file, pred); fclose(template_file); return template_data; } static Ustr *replace_all(const char *str, const replacement_pair_t * repl) { Ustr *retval = USTR_NULL; int i; if (!str || !repl) goto done; if (!(retval = ustr_dup_cstr(str))) goto done; for (i = 0; repl[i].search_for; i++) { ustr_replace_cstr(&retval, repl[i].search_for, repl[i].replace_with, 0); } if (ustr_enomem(retval)) ustr_sc_free(&retval); done: return retval; } static const char * extract_context(Ustr *line) { const char whitespace[] = " \t\n"; size_t off, len; /* check for trailing whitespace */ off = ustr_spn_chrs_rev(line, 0, whitespace, strlen(whitespace)); /* find the length of the last field in line */ len = ustr_cspn_chrs_rev(line, off, whitespace, strlen(whitespace)); if (len == 0) return NULL; return ustr_cstr(line) + ustr_len(line) - (len + off); } static int check_line(genhomedircon_settings_t * s, Ustr *line) { sepol_context_t *ctx_record = NULL; const char *ctx_str; int result; ctx_str = extract_context(line); if (!ctx_str) return STATUS_ERR; result = sepol_context_from_string(s->h_semanage->sepolh, ctx_str, &ctx_record); if (result == STATUS_SUCCESS && ctx_record != NULL) { sepol_msg_set_callback(s->h_semanage->sepolh, NULL, NULL); result = sepol_context_check(s->h_semanage->sepolh, s->policydb, ctx_record); sepol_msg_set_callback(s->h_semanage->sepolh, semanage_msg_relay_handler, s->h_semanage); sepol_context_free(ctx_record); } return result; } static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out, semanage_list_t * tpl, const char *user, const char *seuser, const char *home, const char *role_prefix, const char *level) { replacement_pair_t repl[] = { {.search_for = TEMPLATE_SEUSER,.replace_with = seuser}, {.search_for = TEMPLATE_HOME_DIR,.replace_with = home}, {.search_for = TEMPLATE_ROLE,.replace_with = role_prefix}, {.search_for = TEMPLATE_LEVEL,.replace_with = level}, {NULL, NULL} }; Ustr *line = USTR_NULL; if (fprintf(out, COMMENT_USER_HOME_CONTEXT, user) < 0) return STATUS_ERR; for (; tpl; tpl = tpl->next) { line = replace_all(tpl->data, repl); if (!line) goto fail; if (check_line(s, line) == STATUS_SUCCESS) { if (!ustr_io_putfileline(&line, out)) goto fail; } ustr_sc_free(&line); } return STATUS_SUCCESS; fail: ustr_sc_free(&line); return STATUS_ERR; } static int write_home_root_context(genhomedircon_settings_t * s, FILE * out, semanage_list_t * tpl, char *homedir) { replacement_pair_t repl[] = { {.search_for = TEMPLATE_HOME_ROOT,.replace_with = homedir}, {NULL, NULL} }; Ustr *line = USTR_NULL; for (; tpl; tpl = tpl->next) { line = replace_all(tpl->data, repl); if (!line) goto fail; if (check_line(s, line) == STATUS_SUCCESS) { if (!ustr_io_putfileline(&line, out)) goto fail; } ustr_sc_free(&line); } return STATUS_SUCCESS; fail: ustr_sc_free(&line); return STATUS_ERR; } static int write_user_context(genhomedircon_settings_t * s, FILE * out, semanage_list_t * tpl, const char *user, const char *seuser, const char *role_prefix) { replacement_pair_t repl[] = { {.search_for = TEMPLATE_USER,.replace_with = user}, {.search_for = TEMPLATE_ROLE,.replace_with = role_prefix}, {.search_for = TEMPLATE_SEUSER,.replace_with = seuser}, {NULL, NULL} }; Ustr *line = USTR_NULL; for (; tpl; tpl = tpl->next) { line = replace_all(tpl->data, repl); if (!line) goto fail; if (check_line(s, line) == STATUS_SUCCESS) { if (!ustr_io_putfileline(&line, out)) goto fail; } ustr_sc_free(&line); } return STATUS_SUCCESS; fail: ustr_sc_free(&line); return STATUS_ERR; } static int user_sort_func(semanage_user_t ** arg1, semanage_user_t ** arg2) { return strcmp(semanage_user_get_name(*arg1), semanage_user_get_name(*arg2)); } static int name_user_cmp(char *key, semanage_user_t ** val) { return strcmp(key, semanage_user_get_name(*val)); } static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, const char *sen, const char *pre, const char *h, const char *l) { genhomedircon_user_entry_t *temp = NULL; char *name = NULL; char *sename = NULL; char *prefix = NULL; char *home = NULL; char *level = NULL; temp = malloc(sizeof(genhomedircon_user_entry_t)); if (!temp) goto cleanup; name = strdup(n); if (!name) goto cleanup; sename = strdup(sen); if (!sename) goto cleanup; prefix = strdup(pre); if (!prefix) goto cleanup; home = strdup(h); if (!home) goto cleanup; level = strdup(l); if (!level) goto cleanup; temp->name = name; temp->sename = sename; temp->prefix = prefix; temp->home = home; temp->level = level; temp->next = (*list); (*list) = temp; return STATUS_SUCCESS; cleanup: free(name); free(sename); free(prefix); free(home); free(level); free(temp); return STATUS_ERR; } static void pop_user_entry(genhomedircon_user_entry_t ** list) { genhomedircon_user_entry_t *temp; if (!list || !(*list)) return; temp = *list; *list = temp->next; free(temp->name); free(temp->sename); free(temp->prefix); free(temp->home); free(temp->level); free(temp); } static int set_fallback_user(genhomedircon_settings_t *s, const char *user, const char *prefix, const char *level) { char *fallback_user = strdup(user); char *fallback_user_prefix = strdup(prefix); char *fallback_user_level = NULL; if (level) fallback_user_level = strdup(level); if (fallback_user == NULL || fallback_user_prefix == NULL || (fallback_user_level == NULL && level != NULL)) { free(fallback_user); free(fallback_user_prefix); free(fallback_user_level); return STATUS_ERR; } free(s->fallback_user); free(s->fallback_user_prefix); free(s->fallback_user_level); s->fallback_user = fallback_user; s->fallback_user_prefix = fallback_user_prefix; s->fallback_user_level = fallback_user_level; return STATUS_SUCCESS; } static int setup_fallback_user(genhomedircon_settings_t * s) { semanage_seuser_t **seuser_list = NULL; unsigned int nseusers = 0; semanage_user_key_t *key = NULL; semanage_user_t *u = NULL; const char *name = NULL; const char *seuname = NULL; const char *prefix = NULL; const char *level = NULL; unsigned int i; int retval; int errors = 0; retval = semanage_seuser_list(s->h_semanage, &seuser_list, &nseusers); if (retval < 0 || (nseusers < 1)) { /* if there are no users, this function can't do any other work */ return errors; } for (i = 0; i < nseusers; i++) { name = semanage_seuser_get_name(seuser_list[i]); if (strcmp(name, DEFAULT_LOGIN) == 0) { seuname = semanage_seuser_get_sename(seuser_list[i]); /* find the user structure given the name */ if (semanage_user_key_create(s->h_semanage, seuname, &key) < 0) { errors = STATUS_ERR; break; } if (semanage_user_query(s->h_semanage, key, &u) < 0) { prefix = name; level = FALLBACK_USER_LEVEL; } else { prefix = semanage_user_get_prefix(u); level = semanage_user_get_mlslevel(u); if (!level) level = FALLBACK_USER_LEVEL; } if (set_fallback_user(s, seuname, prefix, level) != 0) errors = STATUS_ERR; semanage_user_key_free(key); if (u) semanage_user_free(u); break; } } for (i = 0; i < nseusers; i++) semanage_seuser_free(seuser_list[i]); free(seuser_list); return errors; } static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, int *errors) { genhomedircon_user_entry_t *head = NULL; semanage_seuser_t **seuser_list = NULL; unsigned int nseusers = 0; semanage_user_t **user_list = NULL; unsigned int nusers = 0; semanage_user_t **u = NULL; const char *name = NULL; const char *seuname = NULL; const char *prefix = NULL; const char *level = NULL; struct passwd pwstorage, *pwent = NULL; unsigned int i; long rbuflen; char *rbuf = NULL; int retval; *errors = 0; retval = semanage_seuser_list(s->h_semanage, &seuser_list, &nseusers); if (retval < 0 || (nseusers < 1)) { /* if there are no users, this function can't do any other work */ return NULL; } if (semanage_user_list(s->h_semanage, &user_list, &nusers) < 0) { nusers = 0; } qsort(user_list, nusers, sizeof(semanage_user_t *), (int (*)(const void *, const void *))&user_sort_func); /* Allocate space for the getpwnam_r buffer */ rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); if (rbuflen <= 0) goto cleanup; rbuf = malloc(rbuflen); if (rbuf == NULL) goto cleanup; for (i = 0; i < nseusers; i++) { seuname = semanage_seuser_get_sename(seuser_list[i]); name = semanage_seuser_get_name(seuser_list[i]); if (strcmp(name,"root") && strcmp(seuname, s->fallback_user) == 0) continue; if (strcmp(name, DEFAULT_LOGIN) == 0) continue; if (strcmp(name, TEMPLATE_SEUSER) == 0) continue; /* %groupname syntax */ if (name[0] == '%') continue; /* find the user structure given the name */ u = bsearch(seuname, user_list, nusers, sizeof(semanage_user_t *), (int (*)(const void *, const void *)) &name_user_cmp); if (u) { prefix = semanage_user_get_prefix(*u); level = semanage_user_get_mlslevel(*u); if (!level) level = FALLBACK_USER_LEVEL; } else { prefix = name; level = FALLBACK_USER_LEVEL; } retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent); if (retval != 0 || pwent == NULL) { if (retval != 0 && retval != ENOENT) { *errors = STATUS_ERR; goto cleanup; } WARN(s->h_semanage, "user %s not in password file", name); continue; } int len = strlen(pwent->pw_dir) -1; for(; len > 0 && pwent->pw_dir[len] == '/'; len--) { pwent->pw_dir[len] = '\0'; } if (strcmp(pwent->pw_dir, "/") == 0) { /* don't relabel / genhomdircon checked to see if root * was the user and if so, set his home directory to * /root */ continue; } if (ignore(pwent->pw_dir)) continue; if (push_user_entry(&head, name, seuname, prefix, pwent->pw_dir, level) != STATUS_SUCCESS) { *errors = STATUS_ERR; break; } } cleanup: free(rbuf); if (*errors) { for (; head; pop_user_entry(&head)) { /* the pop function takes care of all the cleanup so the loop body is just empty */ } } for (i = 0; i < nseusers; i++) { semanage_seuser_free(seuser_list[i]); } free(seuser_list); for (i = 0; i < nusers; i++) { semanage_user_free(user_list[i]); } free(user_list); return head; } static int write_gen_home_dir_context(genhomedircon_settings_t * s, FILE * out, semanage_list_t * user_context_tpl, semanage_list_t * homedir_context_tpl) { genhomedircon_user_entry_t *users; int errors = 0; users = get_users(s, &errors); if (!users && errors) { return STATUS_ERR; } for (; users; pop_user_entry(&users)) { if (write_home_dir_context(s, out, homedir_context_tpl, users->name, users->sename, users->home, users->prefix, users->level)) goto err; if (write_user_context(s, out, user_context_tpl, users->name, users->sename, users->prefix)) goto err; } return STATUS_SUCCESS; err: for (; users; pop_user_entry(&users)) { /* the pop function takes care of all the cleanup * so the loop body is just empty */ } return STATUS_ERR; } /** * @param s settings structure, stores various paths etc. Must never be NULL * @param out the FILE to put all the output in. * @return 0 on success */ static int write_context_file(genhomedircon_settings_t * s, FILE * out) { semanage_list_t *homedirs = NULL; semanage_list_t *h = NULL; semanage_list_t *user_context_tpl = NULL; semanage_list_t *homedir_context_tpl = NULL; semanage_list_t *homeroot_context_tpl = NULL; int retval = STATUS_SUCCESS; homedir_context_tpl = make_template(s, &HOME_DIR_PRED); homeroot_context_tpl = make_template(s, &HOME_ROOT_PRED); user_context_tpl = make_template(s, &USER_CONTEXT_PRED); if (!homedir_context_tpl && !homeroot_context_tpl && !user_context_tpl) goto done; if (write_file_context_header(out) != STATUS_SUCCESS) { retval = STATUS_ERR; goto done; } if (setup_fallback_user(s) != 0) { retval = STATUS_ERR; goto done; } if (homedir_context_tpl || homeroot_context_tpl) { homedirs = get_home_dirs(s); if (!homedirs) { WARN(s->h_semanage, "no home directories were available, exiting without writing"); goto done; } for (h = homedirs; h; h = h->next) { Ustr *temp = ustr_dup_cstr(h->data); if (!temp || !ustr_add_cstr(&temp, "/[^/]*")) { ustr_sc_free(&temp); retval = STATUS_ERR; goto done; } if (write_home_dir_context(s, out, homedir_context_tpl, s->fallback_user, s->fallback_user, ustr_cstr(temp), s->fallback_user_prefix, s->fallback_user_level) != STATUS_SUCCESS) { ustr_sc_free(&temp); retval = STATUS_ERR; goto done; } if (write_home_root_context(s, out, homeroot_context_tpl, h->data) != STATUS_SUCCESS) { ustr_sc_free(&temp); retval = STATUS_ERR; goto done; } ustr_sc_free(&temp); } } if (user_context_tpl) { if (write_user_context(s, out, user_context_tpl, ".*", s->fallback_user, s->fallback_user_prefix) != STATUS_SUCCESS) { retval = STATUS_ERR; goto done; } if (write_gen_home_dir_context(s, out, user_context_tpl, homedir_context_tpl) != STATUS_SUCCESS) { retval = STATUS_ERR; } } done: /* Cleanup */ semanage_list_destroy(&homedirs); semanage_list_destroy(&user_context_tpl); semanage_list_destroy(&homedir_context_tpl); semanage_list_destroy(&homeroot_context_tpl); return retval; } int semanage_genhomedircon(semanage_handle_t * sh, sepol_policydb_t * policydb, int usepasswd, char *ignoredirs) { genhomedircon_settings_t s; FILE *out = NULL; int retval = 0; assert(sh); s.homedir_template_path = semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL); s.fcfilepath = semanage_path(SEMANAGE_TMP, SEMANAGE_FC_HOMEDIRS); s.fallback_user = strdup(FALLBACK_USER); s.fallback_user_prefix = strdup(FALLBACK_USER_PREFIX); s.fallback_user_level = strdup(FALLBACK_USER_LEVEL); if (s.fallback_user == NULL || s.fallback_user_prefix == NULL || s.fallback_user_level == NULL) { retval = STATUS_ERR; goto done; } if (ignoredirs) ignore_setup(ignoredirs); s.usepasswd = usepasswd; s.h_semanage = sh; s.policydb = policydb; if (!(out = fopen(s.fcfilepath, "w"))) { /* couldn't open output file */ ERR(sh, "Could not open the file_context file for writing"); retval = STATUS_ERR; goto done; } retval = write_context_file(&s, out); done: if (out != NULL) fclose(out); free(s.fallback_user); free(s.fallback_user_prefix); free(s.fallback_user_level); ignore_free(); return retval; } libsemanage-2.3/src/genhomedircon.h000066400000000000000000000020711233221606300174040ustar00rootroot00000000000000/* Author: Mark Goldman * * Copyright (C) 2007 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SEMANAGE_GENHOMEDIRCON_H_ #define _SEMANAGE_GENHOMEDIRCON_H_ #include "utilities.h" int semanage_genhomedircon(semanage_handle_t * sh, sepol_policydb_t * policydb, int usepasswd, char *ignoredirs); #endif libsemanage-2.3/src/handle.c000066400000000000000000000275101233221606300160160ustar00rootroot00000000000000/* Author: Joshua Brindle * * Copyright (C) 2004-2005 Tresys Technology, LLC * Copyright (C) 2005 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* This file implements only the publicly-visible handle functions to libsemanage. */ #include #include #include #include #include #include #include #include "direct_api.h" #include "handle.h" #include "debug.h" #include "semanage_conf.h" #include "semanage_store.h" #define SEMANAGE_COMMIT_READ_WAIT 5 #define SEMANAGE_CONF_PATH "/etc/selinux/semanage.conf" #include #include static char *private_selinux_path = NULL; static char *private_semanage_conf_path = NULL; static char *private_file_context_path = NULL; static char *private_file_context_local_path = NULL; static char *private_file_context_homedir_path = NULL; static char *private_homedir_context_path = NULL; static char *private_binary_policy_path = NULL; static char *private_usersconf_path = NULL; static char *private_netfilter_context_path = NULL; static char *private_policy_root = NULL; void semanage_free_root() { free(private_selinux_path); private_selinux_path = NULL; free(private_semanage_conf_path); private_semanage_conf_path = NULL; free(private_file_context_path); private_file_context_path = NULL; free(private_file_context_local_path); private_file_context_local_path = NULL; free(private_file_context_homedir_path); private_file_context_homedir_path = NULL; free(private_homedir_context_path); private_homedir_context_path = NULL; free(private_binary_policy_path); private_binary_policy_path = NULL; free(private_usersconf_path); private_usersconf_path = NULL; free(private_netfilter_context_path); private_netfilter_context_path = NULL; free(private_policy_root); private_policy_root = NULL; } int semanage_set_root(const char *path) { semanage_free_root(); if ( asprintf(&private_selinux_path, "%s/%s", path, selinux_path()) < 0 ) { goto error; } if ( asprintf(&private_semanage_conf_path, "%s/%s", path, SEMANAGE_CONF_PATH) < 0 ) { goto error; } if ( asprintf(&private_file_context_path, "%s/%s", path, selinux_file_context_path()) < 0 ) { goto error; } if ( asprintf(&private_file_context_local_path, "%s/%s", path, selinux_file_context_local_path()) < 0 ) { goto error; } if ( asprintf(&private_homedir_context_path, "%s/%s", path, selinux_homedir_context_path()) < 0 ) { goto error; } if ( asprintf(&private_file_context_homedir_path, "%s/%s", path, selinux_file_context_homedir_path()) < 0 ) { goto error; } if ( asprintf(&private_binary_policy_path, "%s/%s", path, selinux_binary_policy_path()) < 0 ) { goto error; } if ( asprintf(&private_usersconf_path, "%s/%s", path, selinux_usersconf_path()) < 0 ) { goto error; } if ( asprintf(&private_netfilter_context_path, "%s/%s", path, selinux_netfilter_context_path()) < 0 ) { goto error; } if ( asprintf(&private_policy_root, "%s/%s", path, selinux_policy_root()) < 0 ) { goto error; } return 0; error: semanage_free_root(); return -1; } hidden_def(semanage_set_root) const char *semanage_file_context_path() { // printf("private_file_context_path %s\n", private_file_context_path); if (private_file_context_path) return private_file_context_path; return selinux_file_context_path(); } const char *semanage_file_context_local_path() { // printf("private_file_context_local_path %s\n", private_file_context_local_path); if (private_file_context_local_path) return private_file_context_local_path; return selinux_file_context_local_path(); } const char *semanage_file_context_homedir_path() { // printf("private_file_context_homedir_path %s\n", private_file_context_homedir_path); if (private_file_context_homedir_path) return private_file_context_homedir_path; return selinux_file_context_homedir_path(); } const char *semanage_homedir_context_path() { // printf("private_homedir_context_path %s\n", private_homedir_context_path); if (private_homedir_context_path) return private_homedir_context_path; return selinux_homedir_context_path(); } const char *semanage_binary_policy_path() { // printf("private_binary_policy_path %s\n", private_binary_policy_path); if (private_binary_policy_path) return private_binary_policy_path; return selinux_binary_policy_path(); } const char *semanage_usersconf_path() { // printf("private_usersconf_path %s\n", private_usersconf_path); if (private_usersconf_path) return private_usersconf_path; return selinux_usersconf_path(); } const char *semanage_netfilter_context_path() { // printf("private_netfilter_context_path %s\n", private_netfilter_context_path); if (private_netfilter_context_path) return private_netfilter_context_path; return selinux_netfilter_context_path(); } const char *semanage_policy_root() { // printf("private_policy_root %s\n", private_policy_root); if (private_policy_root) return private_policy_root; return selinux_policy_root(); } const char *semanage_selinux_path(void) { // printf("private_selinux_path %s\n", private_selinux_path); if (private_selinux_path) return private_selinux_path; return selinux_path(); } /* Return a fully-qualified path + filename to the semanage * configuration file. The caller must not alter the string returned * (and hence why this function return type is const). * */ const char *semanage_conf_path(void) { if (private_semanage_conf_path && access(private_semanage_conf_path, R_OK) == 0) return private_semanage_conf_path; return SEMANAGE_CONF_PATH; } semanage_handle_t *semanage_handle_create(void) { semanage_handle_t *sh = NULL; const char *conf_name = NULL; /* Allocate handle */ if ((sh = calloc(1, sizeof(semanage_handle_t))) == NULL) goto err; if ((conf_name = semanage_conf_path()) == NULL) goto err; if ((sh->conf = semanage_conf_parse(conf_name)) == NULL) goto err; /* Link to sepol handle */ sh->sepolh = sepol_handle_create(); if (!sh->sepolh) goto err; sepol_msg_set_callback(sh->sepolh, semanage_msg_relay_handler, sh); /* By default do not rebuild the policy on commit * If any changes are made, this flag is ignored */ sh->do_rebuild = 0; /* By default always reload policy after commit if SELinux is enabled. */ sh->do_reload = (is_selinux_enabled() > 0); /* By default always check the file contexts file. */ sh->do_check_contexts = 1; /* By default do not create store */ sh->create_store = 0; /* Set timeout: some default value for now, later use config */ sh->timeout = SEMANAGE_COMMIT_READ_WAIT; /* Set callback */ sh->msg_callback = semanage_msg_default_handler; sh->msg_callback_arg = NULL; return sh; err: semanage_handle_destroy(sh); return NULL; } void semanage_set_rebuild(semanage_handle_t * sh, int do_rebuild) { assert(sh != NULL); sh->do_rebuild = do_rebuild; return; } void semanage_set_reload(semanage_handle_t * sh, int do_reload) { assert(sh != NULL); sh->do_reload = do_reload; return; } void semanage_set_create_store(semanage_handle_t * sh, int create_store) { assert(sh != NULL); sh->create_store = create_store; return; } int semanage_get_disable_dontaudit(semanage_handle_t * sh) { assert(sh != NULL); return sepol_get_disable_dontaudit(sh->sepolh); } void semanage_set_disable_dontaudit(semanage_handle_t * sh, int disable_dontaudit) { assert(sh != NULL); sepol_set_disable_dontaudit(sh->sepolh, disable_dontaudit); return; } int semanage_get_preserve_tunables(semanage_handle_t * sh) { assert(sh != NULL); return sepol_get_preserve_tunables(sh->sepolh); } void semanage_set_preserve_tunables(semanage_handle_t * sh, int preserve_tunables) { assert(sh != NULL); sepol_set_preserve_tunables(sh->sepolh, preserve_tunables); } void semanage_set_check_contexts(semanage_handle_t * sh, int do_check_contexts) { assert(sh != NULL); sh->do_check_contexts = do_check_contexts; return; } int semanage_is_connected(semanage_handle_t * sh) { assert(sh != NULL); return sh->is_connected; } void semanage_select_store(semanage_handle_t * sh, char *storename, enum semanage_connect_type storetype) { assert(sh != NULL); /* This just sets the storename to what the user requests, no verification of existance will be done until connect */ sh->conf->store_path = strdup(storename); assert(sh->conf->store_path); /* no way to return failure */ sh->conf->store_type = storetype; return; } int semanage_is_managed(semanage_handle_t * sh) { assert(sh != NULL); if (sh->is_connected) { ERR(sh, "Already connected."); return -1; } switch (sh->conf->store_type) { case SEMANAGE_CON_DIRECT: return semanage_direct_is_managed(sh); default: ERR(sh, "The connection type specified within your semanage.conf file has not been implemented yet."); /* fall through */ } return -1; } int semanage_mls_enabled(semanage_handle_t * sh) { assert(sh != NULL); switch (sh->conf->store_type) { case SEMANAGE_CON_DIRECT: return semanage_direct_mls_enabled(sh); default: ERR(sh, "The connection type specified within your semanage.conf file has not been implemented yet."); /* fall through */ } return -1; } int semanage_connect(semanage_handle_t * sh) { assert(sh != NULL); switch (sh->conf->store_type) { case SEMANAGE_CON_DIRECT:{ if (semanage_direct_connect(sh) < 0) { return -1; } break; } default:{ ERR(sh, "The connection type specified within your semanage.conf file has not been implemented yet."); return -1; } } sh->is_connected = 1; return 0; } int semanage_access_check(semanage_handle_t * sh) { assert(sh != NULL); switch (sh->conf->store_type) { case SEMANAGE_CON_DIRECT: return semanage_direct_access_check(sh); default: return -1; } return -1; /* unreachable */ } hidden_def(semanage_access_check) int semanage_disconnect(semanage_handle_t * sh) { assert(sh != NULL && sh->funcs != NULL && sh->funcs->disconnect != NULL); if (!sh->is_connected) { return 0; } if (sh->funcs->disconnect(sh) < 0) { return -1; } sh->is_in_transaction = 0; sh->is_connected = 0; sh->modules_modified = 0; return 0; } void semanage_handle_destroy(semanage_handle_t * sh) { if (sh == NULL) return; if (sh->funcs != NULL && sh->funcs->destroy != NULL) sh->funcs->destroy(sh); semanage_conf_destroy(sh->conf); sepol_handle_destroy(sh->sepolh); free(sh); } hidden_def(semanage_handle_destroy) /********************* public transaction functions *********************/ int semanage_begin_transaction(semanage_handle_t * sh) { assert(sh != NULL && sh->funcs != NULL && sh->funcs->begin_trans != NULL); if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } if (sh->is_in_transaction) { return 0; } if (sh->funcs->begin_trans(sh) < 0) { return -1; } sh->is_in_transaction = 1; return 0; } hidden_def(semanage_begin_transaction) int semanage_commit(semanage_handle_t * sh) { int retval; assert(sh != NULL && sh->funcs != NULL && sh->funcs->commit != NULL); if (!sh->is_in_transaction) { ERR(sh, "Will not commit because caller does not have a transaction lock yet."); return -1; } retval = sh->funcs->commit(sh); sh->is_in_transaction = 0; sh->modules_modified = 0; return retval; } libsemanage-2.3/src/handle.h000066400000000000000000000142201233221606300160150ustar00rootroot00000000000000/* Author: Joshua Brindle * Jason Tang * Ivan Gyurdiev * * Copyright (C) 2005 Tresys Technology, LLC * Copyright (C) 2005 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SEMANAGE_INTERNAL_HANDLE_H_ #define _SEMANAGE_INTERNAL_HANDLE_H_ #include #include "handle_internal.h" #include #include "modules.h" #include "semanage_conf.h" #include "database.h" #include "direct_api.h" #include "policy.h" struct semanage_handle { int con_id; /* Connection ID */ /* Error handling */ int msg_level; const char *msg_channel; const char *msg_fname; #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif void (*msg_callback) (void *varg, semanage_handle_t * handle, const char *fmt, ...); void *msg_callback_arg; /* Direct vs Server specific handle */ union { struct semanage_direct_handle direct; } u; /* Libsepol handle */ sepol_handle_t *sepolh; semanage_conf_t *conf; int is_connected; int is_in_transaction; int do_reload; /* whether to reload policy after commit */ int do_rebuild; /* whether to rebuild policy if there were no changes */ int modules_modified; int create_store; /* whether to create the store if it does not exist * this will only have an effect on direct connections */ int do_check_contexts; /* whether to run setfiles check the file contexts file */ /* This timeout is used for transactions and waiting for lock -1 means wait indefinetely 0 means return immediately >0 means wait that many seconds */ int timeout; /* these function pointers will point to the appropriate * routine given the connection type. think of these as * simulating polymorphism for non-OO languages. */ struct semanage_policy_table *funcs; /* Object databases */ #define DBASE_COUNT 19 /* Local modifications */ #define DBASE_LOCAL_USERS_BASE 0 #define DBASE_LOCAL_USERS_EXTRA 1 #define DBASE_LOCAL_USERS 2 #define DBASE_LOCAL_PORTS 3 #define DBASE_LOCAL_INTERFACES 4 #define DBASE_LOCAL_BOOLEANS 5 #define DBASE_LOCAL_FCONTEXTS 6 #define DBASE_LOCAL_SEUSERS 7 #define DBASE_LOCAL_NODES 8 /* Policy + Local modifications */ #define DBASE_POLICY_USERS_BASE 9 #define DBASE_POLICY_USERS_EXTRA 10 #define DBASE_POLICY_USERS 11 #define DBASE_POLICY_PORTS 12 #define DBASE_POLICY_INTERFACES 13 #define DBASE_POLICY_BOOLEANS 14 #define DBASE_POLICY_FCONTEXTS 15 #define DBASE_POLICY_SEUSERS 16 #define DBASE_POLICY_NODES 17 /* Active kernel policy */ #define DBASE_ACTIVE_BOOLEANS 18 dbase_config_t dbase[DBASE_COUNT]; }; const char *semanage_conf_path(void); /* === Local modifications === */ static inline dbase_config_t * semanage_user_base_dbase_local(semanage_handle_t * handle) { return &handle->dbase[DBASE_LOCAL_USERS_BASE]; } static inline dbase_config_t * semanage_user_extra_dbase_local(semanage_handle_t * handle) { return &handle->dbase[DBASE_LOCAL_USERS_EXTRA]; } static inline dbase_config_t * semanage_user_dbase_local(semanage_handle_t * handle) { return &handle->dbase[DBASE_LOCAL_USERS]; } static inline dbase_config_t * semanage_port_dbase_local(semanage_handle_t * handle) { return &handle->dbase[DBASE_LOCAL_PORTS]; } static inline dbase_config_t * semanage_iface_dbase_local(semanage_handle_t * handle) { return &handle->dbase[DBASE_LOCAL_INTERFACES]; } static inline dbase_config_t * semanage_bool_dbase_local(semanage_handle_t * handle) { return &handle->dbase[DBASE_LOCAL_BOOLEANS]; } static inline dbase_config_t * semanage_fcontext_dbase_local(semanage_handle_t * handle) { return &handle->dbase[DBASE_LOCAL_FCONTEXTS]; } static inline dbase_config_t * semanage_seuser_dbase_local(semanage_handle_t * handle) { return &handle->dbase[DBASE_LOCAL_SEUSERS]; } static inline dbase_config_t * semanage_node_dbase_local(semanage_handle_t * handle) { return &handle->dbase[DBASE_LOCAL_NODES]; } /* === Policy + Local modifications === */ static inline dbase_config_t * semanage_user_base_dbase_policy(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_USERS_BASE]; } static inline dbase_config_t * semanage_user_extra_dbase_policy(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_USERS_EXTRA]; } static inline dbase_config_t * semanage_user_dbase_policy(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_USERS]; } static inline dbase_config_t * semanage_port_dbase_policy(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_PORTS]; } static inline dbase_config_t * semanage_iface_dbase_policy(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_INTERFACES]; } static inline dbase_config_t * semanage_bool_dbase_policy(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_BOOLEANS]; } static inline dbase_config_t * semanage_fcontext_dbase_policy(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_FCONTEXTS]; } static inline dbase_config_t * semanage_seuser_dbase_policy(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_SEUSERS]; } static inline dbase_config_t * semanage_node_dbase_policy(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_NODES]; } /* === Active kernel policy === */ static inline dbase_config_t * semanage_bool_dbase_active(semanage_handle_t * handle) { return &handle->dbase[DBASE_ACTIVE_BOOLEANS]; } #endif libsemanage-2.3/src/handle_internal.h000066400000000000000000000014001233221606300177050ustar00rootroot00000000000000#ifndef _SEMANAGE_HANDLE_INTERNAL_H_ #define _SEMANAGE_HANDLE_INTERNAL_H_ #include #include "dso.h" hidden_proto(semanage_begin_transaction) hidden_proto(semanage_handle_destroy) hidden_proto(semanage_reload_policy) hidden_proto(semanage_access_check) hidden_proto(semanage_set_root) extern const char *semanage_selinux_path(void); extern const char *semanage_file_context_path(); extern const char *semanage_file_context_local_path(); extern const char *semanage_file_context_homedir_path(); extern const char *semanage_homedir_context_path(); extern const char *semanage_binary_policy_path(); extern const char *semanage_usersconf_path(); extern const char *semanage_netfilter_context_path(); extern const char *semanage_policy_root(); #endif libsemanage-2.3/src/iface_internal.h000066400000000000000000000023071233221606300175300ustar00rootroot00000000000000#ifndef _SEMANAGE_IFACE_INTERNAL_H_ #define _SEMANAGE_IFACE_INTERNAL_H_ #include #include #include #include "database.h" #include "handle.h" #include "dso.h" hidden_proto(semanage_iface_create) hidden_proto(semanage_iface_compare) hidden_proto(semanage_iface_compare2) hidden_proto(semanage_iface_clone) hidden_proto(semanage_iface_free) hidden_proto(semanage_iface_get_ifcon) hidden_proto(semanage_iface_get_msgcon) hidden_proto(semanage_iface_get_name) hidden_proto(semanage_iface_key_extract) hidden_proto(semanage_iface_key_free) hidden_proto(semanage_iface_set_ifcon) hidden_proto(semanage_iface_set_msgcon) hidden_proto(semanage_iface_set_name) /* IFACE RECORD: metod table */ extern record_table_t SEMANAGE_IFACE_RTABLE; extern int iface_policydb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig); extern void iface_policydb_dbase_release(dbase_config_t * dconfig); extern int iface_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig); extern void iface_file_dbase_release(dbase_config_t * dconfig); #endif libsemanage-2.3/src/iface_record.c000066400000000000000000000074531233221606300171740ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: semanage_iface_t (Network Interface) * Object: semanage_iface_key_t (Network Interface Key) * Implements: record_t (Database Record) * Implements: record_key_t (Database Record Key) */ #include #include typedef sepol_context_t semanage_context_t; typedef sepol_iface_t semanage_iface_t; typedef sepol_iface_key_t semanage_iface_key_t; #define _SEMANAGE_CONTEXT_DEFINED_ #define _SEMANAGE_IFACE_DEFINED_ typedef sepol_iface_t record_t; typedef sepol_iface_key_t record_key_t; #define DBASE_RECORD_DEFINED #include "iface_internal.h" #include "handle.h" #include "database.h" /* Key */ int semanage_iface_compare(const semanage_iface_t * iface, const semanage_iface_key_t * key) { return sepol_iface_compare(iface, key); } hidden_def(semanage_iface_compare) int semanage_iface_compare2(const semanage_iface_t * iface, const semanage_iface_t * iface2) { return sepol_iface_compare2(iface, iface2); } hidden_def(semanage_iface_compare2) static int semanage_iface_compare2_qsort(const semanage_iface_t ** iface, const semanage_iface_t ** iface2) { return sepol_iface_compare2(*iface, *iface2); } int semanage_iface_key_create(semanage_handle_t * handle, const char *name, semanage_iface_key_t ** key_ptr) { return sepol_iface_key_create(handle->sepolh, name, key_ptr); } int semanage_iface_key_extract(semanage_handle_t * handle, const semanage_iface_t * iface, semanage_iface_key_t ** key_ptr) { return sepol_iface_key_extract(handle->sepolh, iface, key_ptr); } hidden_def(semanage_iface_key_extract) void semanage_iface_key_free(semanage_iface_key_t * key) { sepol_iface_key_free(key); } hidden_def(semanage_iface_key_free) /* Name */ const char *semanage_iface_get_name(const semanage_iface_t * iface) { return sepol_iface_get_name(iface); } hidden_def(semanage_iface_get_name) int semanage_iface_set_name(semanage_handle_t * handle, semanage_iface_t * iface, const char *name) { return sepol_iface_set_name(handle->sepolh, iface, name); } hidden_def(semanage_iface_set_name) /* Context */ semanage_context_t *semanage_iface_get_ifcon(const semanage_iface_t * iface) { return sepol_iface_get_ifcon(iface); } hidden_def(semanage_iface_get_ifcon) int semanage_iface_set_ifcon(semanage_handle_t * handle, semanage_iface_t * iface, semanage_context_t * con) { return sepol_iface_set_ifcon(handle->sepolh, iface, con); } hidden_def(semanage_iface_set_ifcon) semanage_context_t *semanage_iface_get_msgcon(const semanage_iface_t * iface) { return sepol_iface_get_msgcon(iface); } hidden_def(semanage_iface_get_msgcon) int semanage_iface_set_msgcon(semanage_handle_t * handle, semanage_iface_t * iface, semanage_context_t * con) { return sepol_iface_set_msgcon(handle->sepolh, iface, con); } hidden_def(semanage_iface_set_msgcon) /* Create/Clone/Destroy */ int semanage_iface_create(semanage_handle_t * handle, semanage_iface_t ** iface_ptr) { return sepol_iface_create(handle->sepolh, iface_ptr); } hidden_def(semanage_iface_create) int semanage_iface_clone(semanage_handle_t * handle, const semanage_iface_t * iface, semanage_iface_t ** iface_ptr) { return sepol_iface_clone(handle->sepolh, iface, iface_ptr); } hidden_def(semanage_iface_clone) void semanage_iface_free(semanage_iface_t * iface) { sepol_iface_free(iface); } hidden_def(semanage_iface_free) /* Record base functions */ record_table_t SEMANAGE_IFACE_RTABLE = { .create = semanage_iface_create, .key_extract = semanage_iface_key_extract, .key_free = semanage_iface_key_free, .clone = semanage_iface_clone, .compare = semanage_iface_compare, .compare2 = semanage_iface_compare2, .compare2_qsort = semanage_iface_compare2_qsort, .free = semanage_iface_free, }; libsemanage-2.3/src/interfaces_file.c000066400000000000000000000076751233221606300177170ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_iface; struct semanage_iface_key; typedef struct semanage_iface record_t; typedef struct semanage_iface_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_file; typedef struct dbase_file dbase_t; #define DBASE_DEFINED #include #include #include #include "iface_internal.h" #include "context_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" static int iface_print(semanage_handle_t * handle, semanage_iface_t * iface, FILE * str) { char *con_str = NULL; const char *name = semanage_iface_get_name(iface); semanage_context_t *ifcon = semanage_iface_get_ifcon(iface); semanage_context_t *msgcon = semanage_iface_get_msgcon(iface); if (fprintf(str, "netifcon %s ", name) < 0) goto err; if (semanage_context_to_string(handle, ifcon, &con_str) < 0) goto err; if (fprintf(str, "%s ", con_str) < 0) goto err; free(con_str); con_str = NULL; if (semanage_context_to_string(handle, msgcon, &con_str) < 0) goto err; if (fprintf(str, "%s\n", con_str) < 0) goto err; free(con_str); con_str = NULL; return STATUS_SUCCESS; err: ERR(handle, "could not print interface %s to stream", name); free(con_str); return STATUS_ERR; } static int iface_parse(semanage_handle_t * handle, parse_info_t * info, semanage_iface_t * iface) { char *str = NULL; semanage_context_t *con = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (!info->ptr) goto last; /* Header */ if (parse_assert_str(handle, info, "netifcon") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* Name */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_iface_set_name(handle, iface, str) < 0) goto err; free(str); str = NULL; /* Interface context */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_context_from_string(handle, str, &con) < 0) { ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s", str, info->filename, info->lineno, info->orig_line); goto err; } if (con == NULL) { ERR(handle, "<> context is not valid for " "interfaces (%s: %u)\n%s", info->filename, info->lineno, info->orig_line); goto err; } free(str); str = NULL; if (semanage_iface_set_ifcon(handle, iface, con) < 0) goto err; semanage_context_free(con); con = NULL; /* Message context */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_context_from_string(handle, str, &con) < 0) { ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s", str, info->filename, info->lineno, info->orig_line); goto err; } if (con == NULL) { ERR(handle, "<> context is not valid for " "interfaces (%s: %u)\n%s", info->filename, info->lineno, info->orig_line); goto err; } free(str); str = NULL; if (semanage_iface_set_msgcon(handle, iface, con) < 0) goto err; semanage_context_free(con); con = NULL; if (parse_assert_space(handle, info) < 0) goto err; return STATUS_SUCCESS; last: parse_dispose_line(info); return STATUS_NODATA; err: ERR(handle, "could not parse interface record"); free(str); semanage_context_free(con); parse_dispose_line(info); return STATUS_ERR; } /* IFACE RECORD: FILE extension: method table */ record_file_table_t SEMANAGE_IFACE_FILE_RTABLE = { .parse = iface_parse, .print = iface_print, }; int iface_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig) { if (dbase_file_init(handle, fname, &SEMANAGE_IFACE_RTABLE, &SEMANAGE_IFACE_FILE_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_FILE_DTABLE; return STATUS_SUCCESS; } void iface_file_dbase_release(dbase_config_t * dconfig) { dbase_file_release(dconfig->dbase); } libsemanage-2.3/src/interfaces_local.c000066400000000000000000000036741233221606300200650ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_iface; struct semanage_iface_key; typedef struct semanage_iface_key record_key_t; typedef struct semanage_iface record_t; #define DBASE_RECORD_DEFINED #include "iface_internal.h" #include "handle.h" #include "database.h" int semanage_iface_modify_local(semanage_handle_t * handle, const semanage_iface_key_t * key, const semanage_iface_t * data) { dbase_config_t *dconfig = semanage_iface_dbase_local(handle); return dbase_modify(handle, dconfig, key, data); } int semanage_iface_del_local(semanage_handle_t * handle, const semanage_iface_key_t * key) { dbase_config_t *dconfig = semanage_iface_dbase_local(handle); return dbase_del(handle, dconfig, key); } int semanage_iface_query_local(semanage_handle_t * handle, const semanage_iface_key_t * key, semanage_iface_t ** response) { dbase_config_t *dconfig = semanage_iface_dbase_local(handle); return dbase_query(handle, dconfig, key, response); } int semanage_iface_exists_local(semanage_handle_t * handle, const semanage_iface_key_t * key, int *response) { dbase_config_t *dconfig = semanage_iface_dbase_local(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_iface_count_local(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_iface_dbase_local(handle); return dbase_count(handle, dconfig, response); } int semanage_iface_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_iface_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_iface_dbase_local(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_iface_list_local(semanage_handle_t * handle, semanage_iface_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_iface_dbase_local(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-2.3/src/interfaces_policy.c000066400000000000000000000026701233221606300202650ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_iface; struct semanage_iface_key; typedef struct semanage_iface_key record_key_t; typedef struct semanage_iface record_t; #define DBASE_RECORD_DEFINED #include "iface_internal.h" #include "handle.h" #include "database.h" int semanage_iface_query(semanage_handle_t * handle, const semanage_iface_key_t * key, semanage_iface_t ** response) { dbase_config_t *dconfig = semanage_iface_dbase_policy(handle); return dbase_query(handle, dconfig, key, response); } int semanage_iface_exists(semanage_handle_t * handle, const semanage_iface_key_t * key, int *response) { dbase_config_t *dconfig = semanage_iface_dbase_policy(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_iface_count(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_iface_dbase_policy(handle); return dbase_count(handle, dconfig, response); } int semanage_iface_iterate(semanage_handle_t * handle, int (*handler) (const semanage_iface_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_iface_dbase_policy(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_iface_list(semanage_handle_t * handle, semanage_iface_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_iface_dbase_policy(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-2.3/src/interfaces_policydb.c000066400000000000000000000041451233221606300205720ustar00rootroot00000000000000/* * Copyright (C) 2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_iface; struct semanage_iface_key; typedef struct semanage_iface record_t; typedef struct semanage_iface_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_policydb; typedef struct dbase_policydb dbase_t; #define DBASE_DEFINED #include #include #include "iface_internal.h" #include "debug.h" #include "database_policydb.h" /* INTERFACE RECRORD (SEPOL): POLICYDB extension: method table */ record_policydb_table_t SEMANAGE_IFACE_POLICYDB_RTABLE = { .add = NULL, .modify = (record_policydb_table_modify_t) sepol_iface_modify, .set = NULL, .query = (record_policydb_table_query_t) sepol_iface_query, .count = (record_policydb_table_count_t) sepol_iface_count, .exists = (record_policydb_table_exists_t) sepol_iface_exists, .iterate = (record_policydb_table_iterate_t) sepol_iface_iterate, }; int iface_policydb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig) { if (dbase_policydb_init(handle, "policy.kern", &SEMANAGE_IFACE_RTABLE, &SEMANAGE_IFACE_POLICYDB_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE; return STATUS_SUCCESS; } void iface_policydb_dbase_release(dbase_config_t * dconfig) { dbase_policydb_release(dconfig->dbase); } libsemanage-2.3/src/libsemanage.map000066400000000000000000000023051233221606300173600ustar00rootroot00000000000000LIBSEMANAGE_1.0 { global: semanage_handle_create; semanage_handle_destroy; semanage_is_managed; semanage_connect; semanage_disconnect; semanage_msg_*; semanage_begin_transaction; semanage_commit; semanage_module_install; semanage_module_install_file; semanage_module_upgrade; semanage_module_upgrade_file; semanage_module_install_base; semanage_module_install_base_file; semanage_module_enable; semanage_module_disable; semanage_module_remove; semanage_module_list; semanage_module_info_datum_destroy; semanage_module_list_nth; semanage_module_get_name; semanage_module_get_version; semanage_select_store; semanage_module_get_enabled; semanage_reload_policy; semanage_set_reload; semanage_set_rebuild; semanage_set_root; semanage_user_*; semanage_bool_*; semanage_seuser_*; semanage_iface_*; semanage_port_*; semanage_context_*; semanage_node_*; semanage_fcontext_*; semanage_access_check; semanage_set_create_store; semanage_is_connected; semanage_get_disable_dontaudit; semanage_set_disable_dontaudit; semanage_mls_enabled; semanage_set_check_contexts; semanage_get_preserve_tunables; semanage_set_preserve_tunables; local: *; }; libsemanage-2.3/src/libsemanage.pc.in000066400000000000000000000005111233221606300176070ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=${prefix} libdir=${exec_prefix}/@libdir@ includedir=@includedir@ Name: libsemanage Description: SELinux management library Version: @VERSION@ URL: http://userspace.selinuxproject.org/ Requires.private: libselinux libsepol ustr Libs: -L${libdir} -lsemanage Libs.private: -lbz2 Cflags: -I${includedir} libsemanage-2.3/src/module_internal.h000066400000000000000000000005451233221606300177500ustar00rootroot00000000000000#ifndef _SEMANAGE_MODULE_INTERNAL_H_ #define _SEMANAGE_MODULE_INTERNAL_H_ #include #include "dso.h" hidden_proto(semanage_module_get_name) hidden_proto(semanage_module_get_version) hidden_proto(semanage_module_get_enabled) hidden_proto(semanage_module_info_datum_destroy) hidden_proto(semanage_module_list_nth) #endif libsemanage-2.3/src/modules.c000066400000000000000000000151651233221606300162360ustar00rootroot00000000000000/* Author: Joshua Brindle * * Copyright (C) 2004-2005 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* This file implements only the publicly-visible module functions to libsemanage. */ #include "direct_api.h" #include "semanage_conf.h" #include "semanage_store.h" #include #include #include #include #include "handle.h" #include "modules.h" #include "debug.h" int semanage_module_install(semanage_handle_t * sh, char *module_data, size_t data_len) { if (sh->funcs->install == NULL) { ERR(sh, "No install function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } else if (!sh->is_in_transaction) { if (semanage_begin_transaction(sh) < 0) { return -1; } } sh->modules_modified = 1; return sh->funcs->install(sh, module_data, data_len); } int semanage_module_install_file(semanage_handle_t * sh, const char *module_name) { if (sh->funcs->install_file == NULL) { ERR(sh, "No install function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } else if (!sh->is_in_transaction) { if (semanage_begin_transaction(sh) < 0) { return -1; } } sh->modules_modified = 1; return sh->funcs->install_file(sh, module_name); } int semanage_module_upgrade(semanage_handle_t * sh, char *module_data, size_t data_len) { if (sh->funcs->upgrade == NULL) { ERR(sh, "No upgrade function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } else if (!sh->is_in_transaction) { if (semanage_begin_transaction(sh) < 0) { return -1; } } sh->modules_modified = 1; int rc = sh->funcs->upgrade(sh, module_data, data_len); if (rc == -5) /* module did not exist */ rc = sh->funcs->install(sh, module_data, data_len); return rc; } int semanage_module_upgrade_file(semanage_handle_t * sh, const char *module_name) { if (sh->funcs->upgrade_file == NULL) { ERR(sh, "No upgrade function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } else if (!sh->is_in_transaction) { if (semanage_begin_transaction(sh) < 0) { return -1; } } sh->modules_modified = 1; int rc = sh->funcs->upgrade_file(sh, module_name); if (rc == -5) /* module did not exist */ rc = sh->funcs->install_file(sh, module_name); return rc; } int semanage_module_install_base(semanage_handle_t * sh, char *module_data, size_t data_len) { if (sh->funcs->install_base == NULL) { ERR(sh, "No install base function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } else if (!sh->is_in_transaction) { if (semanage_begin_transaction(sh) < 0) { return -1; } } sh->modules_modified = 1; return sh->funcs->install_base(sh, module_data, data_len); } int semanage_module_install_base_file(semanage_handle_t * sh, const char *module_name) { if (sh->funcs->install_base_file == NULL) { ERR(sh, "No install base function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } else if (!sh->is_in_transaction) { if (semanage_begin_transaction(sh) < 0) { return -1; } } sh->modules_modified = 1; return sh->funcs->install_base_file(sh, module_name); } int semanage_module_enable(semanage_handle_t * sh, char *module_name) { if (sh->funcs->enable == NULL) { ERR(sh, "No enable function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } else if (!sh->is_in_transaction) { if (semanage_begin_transaction(sh) < 0) { return -1; } } sh->modules_modified = 1; return sh->funcs->enable(sh, module_name); } int semanage_module_disable(semanage_handle_t * sh, char *module_name) { if (sh->funcs->disable == NULL) { ERR(sh, "No disable function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } else if (!sh->is_in_transaction) { if (semanage_begin_transaction(sh) < 0) { return -1; } } sh->modules_modified = 1; return sh->funcs->disable(sh, module_name); } int semanage_module_remove(semanage_handle_t * sh, char *module_name) { if (sh->funcs->remove == NULL) { ERR(sh, "No remove function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } else if (!sh->is_in_transaction) { if (semanage_begin_transaction(sh) < 0) { return -1; } } sh->modules_modified = 1; return sh->funcs->remove(sh, module_name); } int semanage_module_list(semanage_handle_t * sh, semanage_module_info_t ** modinfo, int *num_modules) { if (sh->funcs->list == NULL) { ERR(sh, "No list function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } return sh->funcs->list(sh, modinfo, num_modules); } void semanage_module_info_datum_destroy(semanage_module_info_t * modinfo) { if (modinfo != NULL) { free(modinfo->name); free(modinfo->version); } } hidden_def(semanage_module_info_datum_destroy) semanage_module_info_t *semanage_module_list_nth(semanage_module_info_t * list, int n) { return list + n; } hidden_def(semanage_module_list_nth) const char *semanage_module_get_name(semanage_module_info_t * modinfo) { return modinfo->name; } hidden_def(semanage_module_get_name) int semanage_module_get_enabled(semanage_module_info_t * modinfo) { return modinfo->enabled; } hidden_def(semanage_module_get_enabled) const char *semanage_module_get_version(semanage_module_info_t * modinfo) { return modinfo->version; } hidden_def(semanage_module_get_version) libsemanage-2.3/src/modules.h000066400000000000000000000021131233221606300162300ustar00rootroot00000000000000/* Author: Joshua Brindle * Jason Tang * * Copyright (C) 2005 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SEMANAGE_INTERNAL_MODULES_H_ #define _SEMANAGE_INTERNAL_MODULES_H_ #include "module_internal.h" struct semanage_module_info { char *name; /* Key */ char *version; int enabled; }; #endif libsemanage-2.3/src/node_internal.h000066400000000000000000000033521233221606300174070ustar00rootroot00000000000000#ifndef _SEMANAGE_NODE_INTERNAL_H_ #define _SEMANAGE_NODE_INTERNAL_H_ #include #include #include #include "database.h" #include "handle.h" #include "dso.h" hidden_proto(semanage_node_create) hidden_proto(semanage_node_compare) hidden_proto(semanage_node_compare2) hidden_proto(semanage_node_clone) hidden_proto(semanage_node_free) hidden_proto(semanage_node_key_extract) hidden_proto(semanage_node_key_free) hidden_proto(semanage_node_get_addr) hidden_proto(semanage_node_get_addr_bytes) hidden_proto(semanage_node_get_mask) hidden_proto(semanage_node_get_mask_bytes) hidden_proto(semanage_node_get_proto) hidden_proto(semanage_node_set_addr) hidden_proto(semanage_node_set_addr_bytes) hidden_proto(semanage_node_set_mask) hidden_proto(semanage_node_set_mask_bytes) hidden_proto(semanage_node_set_proto) hidden_proto(semanage_node_get_proto_str) hidden_proto(semanage_node_get_con) hidden_proto(semanage_node_set_con) hidden_proto(semanage_node_list_local) /* NODE RECORD: method table */ extern record_table_t SEMANAGE_NODE_RTABLE; extern int node_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig); extern void node_file_dbase_release(dbase_config_t * dconfig); extern int node_policydb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig); extern void node_policydb_dbase_release(dbase_config_t * dconfig); extern int hidden semanage_node_validate_local(semanage_handle_t * handle); /* ==== Internal (to nodes) API === */ hidden int semanage_node_compare2_qsort(const semanage_node_t ** node, const semanage_node_t ** node2); #endif libsemanage-2.3/src/node_record.c000066400000000000000000000124441233221606300170460ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: semanage_node_t (Network Port) * Object: semanage_node_key_t (Network Port Key) * Implements: record_t (Database Record) * Implements: record_key_t (Database Record Key) */ #include #include #include typedef sepol_context_t semanage_context_t; typedef sepol_node_t semanage_node_t; typedef sepol_node_key_t semanage_node_key_t; #define _SEMANAGE_NODE_DEFINED_ #define _SEMANAGE_CONTEXT_DEFINED_ typedef semanage_node_t record_t; typedef semanage_node_key_t record_key_t; #define DBASE_RECORD_DEFINED #include "node_internal.h" #include "handle.h" #include "database.h" /* Key */ int semanage_node_compare(const semanage_node_t * node, const semanage_node_key_t * key) { return sepol_node_compare(node, key); } hidden_def(semanage_node_compare) int semanage_node_compare2(const semanage_node_t * node, const semanage_node_t * node2) { return sepol_node_compare2(node, node2); } hidden_def(semanage_node_compare2) hidden int semanage_node_compare2_qsort(const semanage_node_t ** node, const semanage_node_t ** node2) { return sepol_node_compare2(*node, *node2); } int semanage_node_key_create(semanage_handle_t * handle, const char *addr, const char *mask, int proto, semanage_node_key_t ** key_ptr) { return sepol_node_key_create(handle->sepolh, addr, mask, proto, key_ptr); } int semanage_node_key_extract(semanage_handle_t * handle, const semanage_node_t * node, semanage_node_key_t ** key_ptr) { return sepol_node_key_extract(handle->sepolh, node, key_ptr); } hidden_def(semanage_node_key_extract) void semanage_node_key_free(semanage_node_key_t * key) { sepol_node_key_free(key); } hidden_def(semanage_node_key_free) /* Address */ int semanage_node_get_addr(semanage_handle_t * handle, const semanage_node_t * node, char **addr_ptr) { return sepol_node_get_addr(handle->sepolh, node, addr_ptr); } hidden_def(semanage_node_get_addr) int semanage_node_get_addr_bytes(semanage_handle_t * handle, const semanage_node_t * node, char **addr, size_t * addr_sz) { return sepol_node_get_addr_bytes(handle->sepolh, node, addr, addr_sz); } hidden_def(semanage_node_get_addr_bytes) int semanage_node_set_addr(semanage_handle_t * handle, semanage_node_t * node, int proto, const char *addr) { return sepol_node_set_addr(handle->sepolh, node, proto, addr); } hidden_def(semanage_node_set_addr) int semanage_node_set_addr_bytes(semanage_handle_t * handle, semanage_node_t * node, const char *addr, size_t addr_sz) { return sepol_node_set_addr_bytes(handle->sepolh, node, addr, addr_sz); } hidden_def(semanage_node_set_addr_bytes) /* Netmask */ int semanage_node_get_mask(semanage_handle_t * handle, const semanage_node_t * node, char **mask_ptr) { return sepol_node_get_mask(handle->sepolh, node, mask_ptr); } hidden_def(semanage_node_get_mask) int semanage_node_get_mask_bytes(semanage_handle_t * handle, const semanage_node_t * node, char **mask, size_t * mask_sz) { return sepol_node_get_mask_bytes(handle->sepolh, node, mask, mask_sz); } hidden_def(semanage_node_get_mask_bytes) int semanage_node_set_mask(semanage_handle_t * handle, semanage_node_t * node, int proto, const char *mask) { return sepol_node_set_mask(handle->sepolh, node, proto, mask); } hidden_def(semanage_node_set_mask) int semanage_node_set_mask_bytes(semanage_handle_t * handle, semanage_node_t * node, const char *mask, size_t mask_sz) { return sepol_node_set_mask_bytes(handle->sepolh, node, mask, mask_sz); } hidden_def(semanage_node_set_mask_bytes) /* Protocol */ int semanage_node_get_proto(const semanage_node_t * node) { return sepol_node_get_proto(node); } hidden_def(semanage_node_get_proto) void semanage_node_set_proto(semanage_node_t * node, int proto) { sepol_node_set_proto(node, proto); } hidden_def(semanage_node_set_proto) const char *semanage_node_get_proto_str(int proto) { return sepol_node_get_proto_str(proto); } hidden_def(semanage_node_get_proto_str) /* Context */ semanage_context_t *semanage_node_get_con(const semanage_node_t * node) { return sepol_node_get_con(node); } hidden_def(semanage_node_get_con) int semanage_node_set_con(semanage_handle_t * handle, semanage_node_t * node, semanage_context_t * con) { return sepol_node_set_con(handle->sepolh, node, con); } hidden_def(semanage_node_set_con) /* Create/Clone/Destroy */ int semanage_node_create(semanage_handle_t * handle, semanage_node_t ** node_ptr) { return sepol_node_create(handle->sepolh, node_ptr); } hidden_def(semanage_node_create) int semanage_node_clone(semanage_handle_t * handle, const semanage_node_t * node, semanage_node_t ** node_ptr) { return sepol_node_clone(handle->sepolh, node, node_ptr); } hidden_def(semanage_node_clone) void semanage_node_free(semanage_node_t * node) { sepol_node_free(node); } hidden_def(semanage_node_free) /* Port base functions */ record_table_t SEMANAGE_NODE_RTABLE = { .create = semanage_node_create, .key_extract = semanage_node_key_extract, .key_free = semanage_node_key_free, .clone = semanage_node_clone, .compare = semanage_node_compare, .compare2 = semanage_node_compare2, .compare2_qsort = semanage_node_compare2_qsort, .free = semanage_node_free, }; libsemanage-2.3/src/nodes_file.c000066400000000000000000000077471233221606300167040ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_node; struct semanage_node_key; typedef struct semanage_node record_t; typedef struct semanage_node_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_file; typedef struct dbase_file dbase_t; #define DBASE_DEFINED #include #include #include #include #include "node_internal.h" #include "context_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" static int node_print(semanage_handle_t * handle, semanage_node_t * node, FILE * str) { char *con_str = NULL; char *addr = NULL; char *mask = NULL; int proto = semanage_node_get_proto(node); const char *proto_str = semanage_node_get_proto_str(proto); semanage_context_t *con = semanage_node_get_con(node); if (semanage_node_get_addr(handle, node, &addr) < 0) goto err; if (semanage_node_get_mask(handle, node, &mask) < 0) goto err; if (semanage_context_to_string(handle, con, &con_str) < 0) goto err; if (fprintf (str, "nodecon %s %s %s %s\n", proto_str, addr, mask, con_str) < 0) goto err; free(addr); free(mask); free(con_str); return STATUS_SUCCESS; err: free(addr); free(mask); free(con_str); ERR(handle, "could not print node to stream"); return STATUS_ERR; } static int node_parse(semanage_handle_t * handle, parse_info_t * info, semanage_node_t * node) { int proto; char *str = NULL; semanage_context_t *con = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (!info->ptr) goto last; /* Header */ if (parse_assert_str(handle, info, "nodecon") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* Protocol */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (!strcasecmp(str, "ipv4")) proto = SEMANAGE_PROTO_IP4; else if (!strcasecmp(str, "ipv6")) proto = SEMANAGE_PROTO_IP6; else { ERR(handle, "invalid protocol \"%s\" (%s: %u):\n%s", str, info->filename, info->lineno, info->orig_line); goto err; } free(str); str = NULL; semanage_node_set_proto(node, proto); /* Address */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_node_set_addr(handle, node, proto, str) < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; free(str); str = NULL; /* Netmask */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_node_set_mask(handle, node, proto, str) < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; free(str); str = NULL; /* Port context */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_context_from_string(handle, str, &con) < 0) { ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s", str, info->filename, info->lineno, info->orig_line); goto err; } if (con == NULL) { ERR(handle, "<> context is not valid " "for nodes (%s: %u):\n%s", info->filename, info->lineno, info->orig_line); goto err; } free(str); str = NULL; if (semanage_node_set_con(handle, node, con) < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; semanage_context_free(con); return STATUS_SUCCESS; last: parse_dispose_line(info); return STATUS_NODATA; err: ERR(handle, "could not parse node record"); free(str); semanage_context_free(con); parse_dispose_line(info); return STATUS_ERR; } /* NODE RECORD: FILE extension: method table */ record_file_table_t SEMANAGE_NODE_FILE_RTABLE = { .parse = node_parse, .print = node_print, }; int node_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig) { if (dbase_file_init(handle, fname, &SEMANAGE_NODE_RTABLE, &SEMANAGE_NODE_FILE_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_FILE_DTABLE; return STATUS_SUCCESS; } void node_file_dbase_release(dbase_config_t * dconfig) { dbase_file_release(dconfig->dbase); } libsemanage-2.3/src/nodes_local.c000066400000000000000000000037151233221606300170460ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_node; struct semanage_node_key; typedef struct semanage_node_key record_key_t; typedef struct semanage_node record_t; #define DBASE_RECORD_DEFINED #include "node_internal.h" #include "handle.h" #include "database.h" int semanage_node_modify_local(semanage_handle_t * handle, const semanage_node_key_t * key, const semanage_node_t * data) { dbase_config_t *dconfig = semanage_node_dbase_local(handle); return dbase_modify(handle, dconfig, key, data); } int semanage_node_del_local(semanage_handle_t * handle, const semanage_node_key_t * key) { dbase_config_t *dconfig = semanage_node_dbase_local(handle); return dbase_del(handle, dconfig, key); } int semanage_node_query_local(semanage_handle_t * handle, const semanage_node_key_t * key, semanage_node_t ** response) { dbase_config_t *dconfig = semanage_node_dbase_local(handle); return dbase_query(handle, dconfig, key, response); } int semanage_node_exists_local(semanage_handle_t * handle, const semanage_node_key_t * key, int *response) { dbase_config_t *dconfig = semanage_node_dbase_local(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_node_count_local(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_node_dbase_local(handle); return dbase_count(handle, dconfig, response); } int semanage_node_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_node_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_node_dbase_local(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_node_list_local(semanage_handle_t * handle, semanage_node_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_node_dbase_local(handle); return dbase_list(handle, dconfig, records, count); } hidden_def(semanage_node_list_local) libsemanage-2.3/src/nodes_policy.c000066400000000000000000000026451233221606300172540ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_node; struct semanage_node_key; typedef struct semanage_node_key record_key_t; typedef struct semanage_node record_t; #define DBASE_RECORD_DEFINED #include "node_internal.h" #include "handle.h" #include "database.h" int semanage_node_query(semanage_handle_t * handle, const semanage_node_key_t * key, semanage_node_t ** response) { dbase_config_t *dconfig = semanage_node_dbase_policy(handle); return dbase_query(handle, dconfig, key, response); } int semanage_node_exists(semanage_handle_t * handle, const semanage_node_key_t * key, int *response) { dbase_config_t *dconfig = semanage_node_dbase_policy(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_node_count(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_node_dbase_policy(handle); return dbase_count(handle, dconfig, response); } int semanage_node_iterate(semanage_handle_t * handle, int (*handler) (const semanage_node_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_node_dbase_policy(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_node_list(semanage_handle_t * handle, semanage_node_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_node_dbase_policy(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-2.3/src/nodes_policydb.c000066400000000000000000000041131233221606300175520ustar00rootroot00000000000000/* * Copyright (C) 2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_node; struct semanage_node_key; typedef struct semanage_node record_t; typedef struct semanage_node_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_policydb; typedef struct dbase_policydb dbase_t; #define DBASE_DEFINED #include #include #include "node_internal.h" #include "debug.h" #include "database_policydb.h" /* NODE RECORD (SEPOL): POLICYDB extension : method table */ record_policydb_table_t SEMANAGE_NODE_POLICYDB_RTABLE = { .add = NULL, .modify = (record_policydb_table_modify_t) sepol_node_modify, .set = NULL, .query = (record_policydb_table_query_t) sepol_node_query, .count = (record_policydb_table_count_t) sepol_node_count, .exists = (record_policydb_table_exists_t) sepol_node_exists, .iterate = (record_policydb_table_iterate_t) sepol_node_iterate, }; int node_policydb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig) { if (dbase_policydb_init(handle, "policy.kern", &SEMANAGE_NODE_RTABLE, &SEMANAGE_NODE_POLICYDB_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE; return STATUS_SUCCESS; } void node_policydb_dbase_release(dbase_config_t * dconfig) { dbase_policydb_release(dconfig->dbase); } libsemanage-2.3/src/parse_utils.c000066400000000000000000000137461233221606300171230ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #include #include #include #include #include #include #include #include "parse_utils.h" #include "debug.h" int parse_init(semanage_handle_t * handle, const char *filename, void *parse_arg, parse_info_t ** info) { parse_info_t *tmp_info = (parse_info_t *) malloc(sizeof(parse_info_t)); if (!tmp_info) { ERR(handle, "out of memory, could not allocate parse structure"); return STATUS_ERR; } tmp_info->filename = filename; tmp_info->file_stream = NULL; tmp_info->working_copy = NULL; tmp_info->orig_line = NULL; tmp_info->ptr = NULL; tmp_info->lineno = 0; tmp_info->parse_arg = parse_arg; *info = tmp_info; return STATUS_SUCCESS; } void parse_release(parse_info_t * info) { parse_close(info); parse_dispose_line(info); free(info); } int parse_open(semanage_handle_t * handle, parse_info_t * info) { info->file_stream = fopen(info->filename, "r"); if (!info->file_stream && (errno != ENOENT)) { ERR(handle, "could not open file %s: %s", info->filename, strerror(errno)); return STATUS_ERR; } if (info->file_stream) __fsetlocking(info->file_stream, FSETLOCKING_BYCALLER); return STATUS_SUCCESS; } void parse_close(parse_info_t * info) { if (info->file_stream) fclose(info->file_stream); info->file_stream = NULL; } void parse_dispose_line(parse_info_t * info) { if (info->orig_line) { free(info->orig_line); info->orig_line = NULL; } if (info->working_copy) { free(info->working_copy); info->working_copy = NULL; } info->ptr = NULL; } int parse_skip_space(semanage_handle_t * handle, parse_info_t * info) { size_t buf_len = 0; ssize_t len; int lineno = info->lineno; char *buffer = NULL; char *ptr; if (info->ptr) { while (*(info->ptr) && isspace(*(info->ptr))) info->ptr++; if (*(info->ptr)) return STATUS_SUCCESS; } parse_dispose_line(info); while (info->file_stream && ((len = getline(&buffer, &buf_len, info->file_stream)) > 0)) { lineno++; /* Eat newline, preceding whitespace */ if (buffer[len - 1] == '\n') buffer[len - 1] = '\0'; ptr = buffer; while (*ptr && isspace(*ptr)) ptr++; /* Skip comments and blank lines */ if ((*ptr) && *ptr != '#') { char *tmp = strdup(buffer); if (!tmp) goto omem; info->lineno = lineno; info->working_copy = buffer; info->orig_line = tmp; info->ptr = ptr; return STATUS_SUCCESS; } } free(buffer); buffer = NULL; return STATUS_SUCCESS; omem: ERR(handle, "out of memory, could not allocate buffer"); free(buffer); return STATUS_ERR; } int parse_assert_noeof(semanage_handle_t * handle, parse_info_t * info) { if (!info->ptr) { ERR(handle, "unexpected end of file (%s: %u)", info->filename, info->lineno); return STATUS_ERR; } return STATUS_SUCCESS; } int parse_assert_space(semanage_handle_t * handle, parse_info_t * info) { if (parse_assert_noeof(handle, info) < 0) return STATUS_ERR; if (*(info->ptr) && !isspace(*(info->ptr))) { ERR(handle, "missing whitespace (%s: %u):\n%s", info->filename, info->lineno, info->orig_line); return STATUS_ERR; } if (parse_skip_space(handle, info) < 0) return STATUS_ERR; return STATUS_SUCCESS; } int parse_assert_ch(semanage_handle_t * handle, parse_info_t * info, const char ch) { if (parse_assert_noeof(handle, info) < 0) return STATUS_ERR; if (*(info->ptr) != ch) { ERR(handle, "expected character \'%c\', but found \'%c\' " "(%s: %u):\n%s", ch, *(info->ptr), info->filename, info->lineno, info->orig_line); return STATUS_ERR; } info->ptr++; return STATUS_SUCCESS; } int parse_assert_str(semanage_handle_t * handle, parse_info_t * info, const char *assert_str) { size_t len = strlen(assert_str); if (parse_assert_noeof(handle, info) < 0) return STATUS_ERR; if (strncmp(info->ptr, assert_str, len)) { ERR(handle, "experted string \"%s\", but found \"%s\" " "(%s: %u):\n%s", assert_str, info->ptr, info->filename, info->lineno, info->orig_line); return STATUS_ERR; } info->ptr += len; return STATUS_SUCCESS; } int parse_optional_ch(parse_info_t * info, const char ch) { if (!info->ptr) return STATUS_NODATA; if (*(info->ptr) != ch) return STATUS_NODATA; info->ptr++; return STATUS_SUCCESS; } int parse_optional_str(parse_info_t * info, const char *str) { size_t len = strlen(str); if (strncmp(info->ptr, str, len)) return STATUS_NODATA; info->ptr += len; return STATUS_SUCCESS; } int parse_fetch_int(semanage_handle_t * handle, parse_info_t * info, int *num, char delim) { char *str = NULL; char *test = NULL; int value = 0; if (parse_fetch_string(handle, info, &str, delim) < 0) goto err; if (!isdigit((int)*str)) { ERR(handle, "expected a numeric value: (%s: %u)\n%s", info->filename, info->lineno, info->orig_line); goto err; } value = strtol(str, &test, 10); if (*test != '\0') { ERR(handle, "could not parse numeric value \"%s\": " "(%s: %u)\n%s", str, info->filename, info->lineno, info->orig_line); goto err; } *num = value; free(str); return STATUS_SUCCESS; err: ERR(handle, "could not fetch numeric value"); free(str); return STATUS_ERR; } int parse_fetch_string(semanage_handle_t * handle, parse_info_t * info, char **str, char delim) { char *start = info->ptr; int len = 0; char *tmp_str = NULL; if (parse_assert_noeof(handle, info) < 0) goto err; while (*(info->ptr) && !isspace(*(info->ptr)) && (*(info->ptr) != delim)) { info->ptr++; len++; } if (len == 0) { ERR(handle, "expected non-empty string, but did not " "find one (%s: %u):\n%s", info->filename, info->lineno, info->orig_line); goto err; } tmp_str = (char *)malloc(len + 1); if (!tmp_str) { ERR(handle, "out of memory"); goto err; } strncpy(tmp_str, start, len); *(tmp_str + len) = '\0'; *str = tmp_str; return STATUS_SUCCESS; err: ERR(handle, "could not fetch string value"); return STATUS_ERR; } libsemanage-2.3/src/parse_utils.h000066400000000000000000000053271233221606300171240ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_PARSE_UTILS_INTERNAL_H_ #define _SEMANAGE_PARSE_UTILS_INTERNAL_H_ #include #include typedef struct parse_info { unsigned int lineno; /* Current line number */ char *orig_line; /* Original copy of the line being parsed */ char *working_copy; /* Working copy of the line being parsed */ char *ptr; /* Current parsing location */ const char *filename; /* Input stream file name */ FILE *file_stream; /* Input stream handle */ void *parse_arg; /* Caller supplied argument */ } parse_info_t; /* Initialize structure */ extern int parse_init(semanage_handle_t * handle, const char *filename, void *parse_arg, parse_info_t ** info); /* Release structure */ extern void parse_release(parse_info_t * info); /* Open file */ extern int parse_open(semanage_handle_t * handle, parse_info_t * info); /* Close file */ extern void parse_close(parse_info_t * info); /* Release resources for current line */ extern void parse_dispose_line(parse_info_t * info); /* Skip all whitespace and comments */ extern int parse_skip_space(semanage_handle_t * handle, parse_info_t * info); /* Throw an error if we're at the EOF */ extern int parse_assert_noeof(semanage_handle_t * handle, parse_info_t * info); /* Throw an error if no whitespace follows, * otherwise eat the whitespace */ extern int parse_assert_space(semanage_handle_t * handle, parse_info_t * info); /* Throw an error if the specified character * does not follow, otherwise eat that character */ extern int parse_assert_ch(semanage_handle_t * handle, parse_info_t * info, const char ch); /* Throw an error if the specified string * does not follow is not found, otherwise * eat the string */ extern int parse_assert_str(semanage_handle_t * handle, parse_info_t * info, const char *assert_str); /* Eat the optional character, if found, * or return STATUS_NODATA */ extern int parse_optional_ch(parse_info_t * info, const char ch); /* Eat the optional string, if found, * or return STATUS_NODATA */ extern int parse_optional_str(parse_info_t * info, const char *str); /* Extract the next integer, and move * the read pointer past it. Stop if * the optional character delim is encountered, * or if whitespace/eof is encountered */ int parse_fetch_int(semanage_handle_t * hgandle, parse_info_t * info, int *num, char delim); /* Extract the next string (delimited by * whitespace), and move the read pointer past it. * Stop of the optional character delim is encountered, * or if whitespace/eof is encountered. Fail if the * string is of length 0. */ extern int parse_fetch_string(semanage_handle_t * handle, parse_info_t * info, char **str_ptr, char delim); #endif libsemanage-2.3/src/policy.h000066400000000000000000000052531233221606300160670ustar00rootroot00000000000000/* Author: Joshua Brindle * Jason Tang * * Copyright (C) 2005 Tresys Technology, LLC * Copyright (C) 2005 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _SEMANAGE_POLICY_INTERNAL_H_ #define _SEMANAGE_POLICY_INTERNAL_H_ #include "modules.h" /* Circular dependency */ struct semanage_handle; /* Backend dependent portion */ struct semanage_policy_table { /* Returns the current policy serial/commit number * A negative number is returned in case of failre */ int (*get_serial) (struct semanage_handle *); /* Destroy a connection */ void (*destroy) (struct semanage_handle *); /* Disconnect from policy */ int (*disconnect) (struct semanage_handle *); /* Begin a policy transaction */ int (*begin_trans) (struct semanage_handle *); /* Commit a policy transaction */ int (*commit) (struct semanage_handle *); /* Install a policy module */ int (*install) (struct semanage_handle *, char *, size_t); /* Install a policy module */ int (*install_file) (struct semanage_handle *, const char *); /* Upgrade a policy module */ int (*upgrade) (struct semanage_handle *, char *, size_t); /* Upgrade a policy module */ int (*upgrade_file) (struct semanage_handle *, const char *); /* Enable a policy module */ int (*enable) (struct semanage_handle *, char *); /* Disable a policy module */ int (*disable) (struct semanage_handle *, char *); /* Remove a policy module */ int (*remove) (struct semanage_handle *, char *); /* List policy modules */ int (*list) (struct semanage_handle *, semanage_module_info_t **, int *); /* Install base policy */ int (*install_base) (struct semanage_handle *, char *, size_t); /* Install a base module */ int (*install_base_file) (struct semanage_handle *, const char *); }; /* Should be backend independent */ extern int semanage_base_merge_components(struct semanage_handle *handle); extern int semanage_commit_components(struct semanage_handle *handle); #endif libsemanage-2.3/src/policy_components.c000066400000000000000000000132211233221606300203210ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #include #include "policy.h" #include "handle.h" #include "database.h" #include "modules.h" #include "debug.h" /* Powers of two only */ #define MODE_SET 1 #define MODE_MODIFY 2 #define MODE_SORT 4 static int clear_obsolete(semanage_handle_t * handle, record_t ** records, unsigned int nrecords, dbase_config_t * src, dbase_config_t * dst) { record_key_t *key = NULL; unsigned int i; dbase_table_t *src_dtable = src->dtable; dbase_table_t *dst_dtable = dst->dtable; record_table_t *rtable = src_dtable->get_rtable(src->dbase); for (i = 0; i < nrecords; i++) { int exists; if (rtable->key_extract(handle, records[i], &key) < 0) goto err; if (dst_dtable->exists(handle, dst->dbase, key, &exists) < 0) goto err; if (!exists) { if (src_dtable->del(handle, src->dbase, key) < 0) goto err; rtable->free(records[i]); records[i] = NULL; /* FIXME: notice to user */ /* INFO(handle, "boolean %s is obsolete, unsetting configured value..."); */ } rtable->key_free(key); } return STATUS_SUCCESS; err: /* FIXME: handle error */ rtable->key_free(key); return STATUS_ERR; } static int load_records(semanage_handle_t * handle, dbase_config_t * dst, record_t ** records, unsigned int nrecords, int mode) { unsigned int i; record_key_t *rkey = NULL; dbase_t *dbase = dst->dbase; dbase_table_t *dtable = dst->dtable; record_table_t *rtable = dtable->get_rtable(dbase); for (i = 0; i < nrecords; i++) { /* Possibly obsoleted */ if (!records[i]) continue; if (rtable->key_extract(handle, records[i], &rkey) < 0) goto err; if (mode & MODE_SET && dtable->set(handle, dbase, rkey, records[i]) < 0) goto err; else if (mode & MODE_MODIFY && dtable->modify(handle, dbase, rkey, records[i]) < 0) goto err; rtable->key_free(rkey); } return STATUS_SUCCESS; err: /* FIXME: handle error */ rtable->key_free(rkey); return STATUS_ERR; } typedef struct load_table { dbase_config_t *src; dbase_config_t *dst; int mode; } load_table_t; /* This function must be called AFTER all modules are loaded. * Modules could be represented as a database, in which case * they should be loaded at the beginning of this function */ int semanage_base_merge_components(semanage_handle_t * handle) { unsigned int i, j; int rc = STATUS_SUCCESS; /* Order is important here - change things carefully. * System components first, local next. Verify runs with * mutual dependencies are ran after everything is merged */ load_table_t components[] = { {semanage_user_base_dbase_local(handle), semanage_user_base_dbase_policy(handle), MODE_MODIFY}, {semanage_user_extra_dbase_local(handle), semanage_user_extra_dbase_policy(handle), MODE_MODIFY}, {semanage_port_dbase_local(handle), semanage_port_dbase_policy(handle), MODE_MODIFY}, {semanage_iface_dbase_local(handle), semanage_iface_dbase_policy(handle), MODE_MODIFY}, {semanage_bool_dbase_local(handle), semanage_bool_dbase_policy(handle), MODE_SET}, {semanage_seuser_dbase_local(handle), semanage_seuser_dbase_policy(handle), MODE_MODIFY}, {semanage_node_dbase_local(handle), semanage_node_dbase_policy(handle), MODE_MODIFY | MODE_SORT}, }; const unsigned int CCOUNT = sizeof(components) / sizeof(components[0]); /* Merge components into policy (and validate) */ for (i = 0; i < CCOUNT; i++) { record_t **records = NULL; unsigned int nrecords = 0; dbase_config_t *src = components[i].src; dbase_config_t *dst = components[i].dst; int mode = components[i].mode; record_table_t *rtable = src->dtable->get_rtable(src->dbase); /* Must invoke cache function first */ if (src->dtable->cache(handle, src->dbase) < 0) goto err; if (dst->dtable->cache(handle, dst->dbase) < 0) goto err; /* List all records */ if (src->dtable->list(handle, src->dbase, &records, &nrecords) < 0) goto err; /* Sort records on MODE_SORT */ if (mode & MODE_SORT) { qsort(records, nrecords, sizeof(record_t *), (int (*)(const void *, const void *))rtable-> compare2_qsort); } /* Clear obsolete ones for MODE_SET */ if (mode & MODE_SET && clear_obsolete(handle, records, nrecords, src, dst) < 0) { rc = STATUS_ERR; goto dbase_exit; } /* Load records */ if (load_records(handle, dst, records, nrecords, mode) < 0) { rc = STATUS_ERR; goto dbase_exit; } /* Cleanup */ dbase_exit: for (j = 0; j < nrecords; j++) rtable->free(records[j]); free(records); /* Abort on error */ if (rc < 0) goto err; } return rc; err: ERR(handle, "could not merge local modifications into policy"); return STATUS_ERR; } int semanage_commit_components(semanage_handle_t * handle) { int i; dbase_config_t *components[] = { semanage_iface_dbase_local(handle), semanage_bool_dbase_local(handle), semanage_user_base_dbase_local(handle), semanage_user_extra_dbase_local(handle), semanage_user_extra_dbase_policy(handle), semanage_port_dbase_local(handle), semanage_fcontext_dbase_local(handle), semanage_fcontext_dbase_policy(handle), semanage_seuser_dbase_local(handle), semanage_seuser_dbase_policy(handle), semanage_bool_dbase_active(handle), semanage_node_dbase_local(handle), }; const int CCOUNT = sizeof(components) / sizeof(components[0]); for (i = 0; i < CCOUNT; i++) { /* Flush to disk */ if (components[i]->dtable->flush(handle, components[i]->dbase) < 0) goto err; } return STATUS_SUCCESS; err: ERR(handle, "could not commit local/active modifications"); for (i = 0; i < CCOUNT; i++) components[i]->dtable->drop_cache(components[i]->dbase); return STATUS_ERR; } libsemanage-2.3/src/port_internal.h000066400000000000000000000030561233221606300174470ustar00rootroot00000000000000#ifndef _SEMANAGE_PORT_INTERNAL_H_ #define _SEMANAGE_PORT_INTERNAL_H_ #include #include #include #include "database.h" #include "handle.h" #include "dso.h" hidden_proto(semanage_port_create) hidden_proto(semanage_port_compare) hidden_proto(semanage_port_compare2) hidden_proto(semanage_port_clone) hidden_proto(semanage_port_free) hidden_proto(semanage_port_key_extract) hidden_proto(semanage_port_key_free) hidden_proto(semanage_port_get_high) hidden_proto(semanage_port_get_low) hidden_proto(semanage_port_set_port) hidden_proto(semanage_port_set_range) hidden_proto(semanage_port_get_proto) hidden_proto(semanage_port_set_proto) hidden_proto(semanage_port_get_proto_str) hidden_proto(semanage_port_get_con) hidden_proto(semanage_port_set_con) hidden_proto(semanage_port_list_local) /* PORT RECORD: method table */ extern record_table_t SEMANAGE_PORT_RTABLE; extern int port_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig); extern void port_file_dbase_release(dbase_config_t * dconfig); extern int port_policydb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig); extern void port_policydb_dbase_release(dbase_config_t * dconfig); extern int hidden semanage_port_validate_local(semanage_handle_t * handle); /* ==== Internal (to ports) API === */ hidden int semanage_port_compare2_qsort(const semanage_port_t ** port, const semanage_port_t ** port2); #endif libsemanage-2.3/src/port_record.c000066400000000000000000000077121233221606300171070ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: semanage_port_t (Network Port) * Object: semanage_port_key_t (Network Port Key) * Implements: record_t (Database Record) * Implements: record_key_t (Database Record Key) */ #include #include typedef sepol_context_t semanage_context_t; typedef sepol_port_t semanage_port_t; typedef sepol_port_key_t semanage_port_key_t; #define _SEMANAGE_PORT_DEFINED_ #define _SEMANAGE_CONTEXT_DEFINED_ typedef semanage_port_t record_t; typedef semanage_port_key_t record_key_t; #define DBASE_RECORD_DEFINED #include "port_internal.h" #include "handle.h" #include "database.h" /* Key */ int semanage_port_compare(const semanage_port_t * port, const semanage_port_key_t * key) { return sepol_port_compare(port, key); } hidden_def(semanage_port_compare) int semanage_port_compare2(const semanage_port_t * port, const semanage_port_t * port2) { return sepol_port_compare2(port, port2); } hidden_def(semanage_port_compare2) hidden int semanage_port_compare2_qsort(const semanage_port_t ** port, const semanage_port_t ** port2) { return sepol_port_compare2(*port, *port2); } int semanage_port_key_create(semanage_handle_t * handle, int low, int high, int proto, semanage_port_key_t ** key_ptr) { return sepol_port_key_create(handle->sepolh, low, high, proto, key_ptr); } int semanage_port_key_extract(semanage_handle_t * handle, const semanage_port_t * port, semanage_port_key_t ** key_ptr) { return sepol_port_key_extract(handle->sepolh, port, key_ptr); } hidden_def(semanage_port_key_extract) void semanage_port_key_free(semanage_port_key_t * key) { sepol_port_key_free(key); } hidden_def(semanage_port_key_free) /* Protocol */ int semanage_port_get_proto(const semanage_port_t * port) { return sepol_port_get_proto(port); } hidden_def(semanage_port_get_proto) void semanage_port_set_proto(semanage_port_t * port, int proto) { sepol_port_set_proto(port, proto); } hidden_def(semanage_port_set_proto) const char *semanage_port_get_proto_str(int proto) { return sepol_port_get_proto_str(proto); } hidden_def(semanage_port_get_proto_str) /* Port */ int semanage_port_get_low(const semanage_port_t * port) { return sepol_port_get_low(port); } hidden_def(semanage_port_get_low) int semanage_port_get_high(const semanage_port_t * port) { return sepol_port_get_high(port); } hidden_def(semanage_port_get_high) void semanage_port_set_port(semanage_port_t * port, int port_num) { sepol_port_set_port(port, port_num); } hidden_def(semanage_port_set_port) void semanage_port_set_range(semanage_port_t * port, int low, int high) { sepol_port_set_range(port, low, high); } hidden_def(semanage_port_set_range) /* Context */ semanage_context_t *semanage_port_get_con(const semanage_port_t * port) { return sepol_port_get_con(port); } hidden_def(semanage_port_get_con) int semanage_port_set_con(semanage_handle_t * handle, semanage_port_t * port, semanage_context_t * con) { return sepol_port_set_con(handle->sepolh, port, con); } hidden_def(semanage_port_set_con) /* Create/Clone/Destroy */ int semanage_port_create(semanage_handle_t * handle, semanage_port_t ** port_ptr) { return sepol_port_create(handle->sepolh, port_ptr); } hidden_def(semanage_port_create) int semanage_port_clone(semanage_handle_t * handle, const semanage_port_t * port, semanage_port_t ** port_ptr) { return sepol_port_clone(handle->sepolh, port, port_ptr); } hidden_def(semanage_port_clone) void semanage_port_free(semanage_port_t * port) { sepol_port_free(port); } hidden_def(semanage_port_free) /* Port base functions */ record_table_t SEMANAGE_PORT_RTABLE = { .create = semanage_port_create, .key_extract = semanage_port_key_extract, .key_free = semanage_port_key_free, .clone = semanage_port_clone, .compare = semanage_port_compare, .compare2 = semanage_port_compare2, .compare2_qsort = semanage_port_compare2_qsort, .free = semanage_port_free, }; libsemanage-2.3/src/ports_file.c000066400000000000000000000104371233221606300167310ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_port; struct semanage_port_key; typedef struct semanage_port record_t; typedef struct semanage_port_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_file; typedef struct dbase_file dbase_t; #define DBASE_DEFINED #include #include #include #include #include "port_internal.h" #include "context_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" static int port_print(semanage_handle_t * handle, semanage_port_t * port, FILE * str) { char *con_str = NULL; int low = semanage_port_get_low(port); int high = semanage_port_get_high(port); int proto = semanage_port_get_proto(port); const char *proto_str = semanage_port_get_proto_str(proto); semanage_context_t *con = semanage_port_get_con(port); if (fprintf(str, "portcon %s ", proto_str) < 0) goto err; if (low == high) { if (fprintf(str, "%d ", low) < 0) goto err; } else { if (fprintf(str, "%d - %d ", low, high) < 0) goto err; } if (semanage_context_to_string(handle, con, &con_str) < 0) goto err; if (fprintf(str, "%s\n", con_str) < 0) goto err; free(con_str); return STATUS_SUCCESS; err: ERR(handle, "could not print port range %u - %u (%s) to stream", low, high, proto_str); free(con_str); return STATUS_ERR; } static int port_parse(semanage_handle_t * handle, parse_info_t * info, semanage_port_t * port) { int low, high; char *str = NULL; semanage_context_t *con = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (!info->ptr) goto last; /* Header */ if (parse_assert_str(handle, info, "portcon") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* Protocol */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (!strcasecmp(str, "tcp")) semanage_port_set_proto(port, SEMANAGE_PROTO_TCP); else if (!strcasecmp(str, "udp")) semanage_port_set_proto(port, SEMANAGE_PROTO_UDP); else { ERR(handle, "invalid protocol \"%s\" (%s: %u):\n%s", str, info->filename, info->lineno, info->orig_line); goto err; } free(str); str = NULL; /* Range/Port */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_fetch_int(handle, info, &low, '-') < 0) goto err; /* If range (-) does not follow immediately, require a space * In other words, the space here is optional, but only * in the ranged case, not in the single port case, * so do a custom test */ if (*(info->ptr) && *(info->ptr) != '-') { if (parse_assert_space(handle, info) < 0) goto err; } if (parse_optional_ch(info, '-') != STATUS_NODATA) { if (parse_skip_space(handle, info) < 0) goto err; if (parse_fetch_int(handle, info, &high, ' ') < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; semanage_port_set_range(port, low, high); } else semanage_port_set_port(port, low); /* Port context */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_context_from_string(handle, str, &con) < 0) { ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s", str, info->filename, info->lineno, info->orig_line); goto err; } if (con == NULL) { ERR(handle, "<> context is not valid " "for ports (%s: %u):\n%s", info->filename, info->lineno, info->orig_line); goto err; } free(str); str = NULL; if (semanage_port_set_con(handle, port, con) < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; semanage_context_free(con); return STATUS_SUCCESS; last: parse_dispose_line(info); return STATUS_NODATA; err: ERR(handle, "could not parse port record"); free(str); semanage_context_free(con); parse_dispose_line(info); return STATUS_ERR; } /* PORT RECORD: FILE extension: method table */ record_file_table_t SEMANAGE_PORT_FILE_RTABLE = { .parse = port_parse, .print = port_print, }; int port_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig) { if (dbase_file_init(handle, fname, &SEMANAGE_PORT_RTABLE, &SEMANAGE_PORT_FILE_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_FILE_DTABLE; return STATUS_SUCCESS; } void port_file_dbase_release(dbase_config_t * dconfig) { dbase_file_release(dconfig->dbase); } libsemanage-2.3/src/ports_local.c000066400000000000000000000073671233221606300171140ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_port; struct semanage_port_key; typedef struct semanage_port_key record_key_t; typedef struct semanage_port record_t; #define DBASE_RECORD_DEFINED #include #include "port_internal.h" #include "debug.h" #include "handle.h" #include "database.h" int semanage_port_modify_local(semanage_handle_t * handle, const semanage_port_key_t * key, const semanage_port_t * data) { dbase_config_t *dconfig = semanage_port_dbase_local(handle); return dbase_modify(handle, dconfig, key, data); } int semanage_port_del_local(semanage_handle_t * handle, const semanage_port_key_t * key) { dbase_config_t *dconfig = semanage_port_dbase_local(handle); return dbase_del(handle, dconfig, key); } int semanage_port_query_local(semanage_handle_t * handle, const semanage_port_key_t * key, semanage_port_t ** response) { dbase_config_t *dconfig = semanage_port_dbase_local(handle); return dbase_query(handle, dconfig, key, response); } int semanage_port_exists_local(semanage_handle_t * handle, const semanage_port_key_t * key, int *response) { dbase_config_t *dconfig = semanage_port_dbase_local(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_port_count_local(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_port_dbase_local(handle); return dbase_count(handle, dconfig, response); } int semanage_port_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_port_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_port_dbase_local(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_port_list_local(semanage_handle_t * handle, semanage_port_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_port_dbase_local(handle); return dbase_list(handle, dconfig, records, count); } hidden_def(semanage_port_list_local) int hidden semanage_port_validate_local(semanage_handle_t * handle) { semanage_port_t **ports = NULL; unsigned int nports = 0; unsigned int i = 0, j = 0; /* List and sort the ports */ if (semanage_port_list_local(handle, &ports, &nports) < 0) goto err; qsort(ports, nports, sizeof(semanage_port_t *), (int (*)(const void *, const void *)) &semanage_port_compare2_qsort); /* Test each port for overlap */ while (i < nports) { int proto = semanage_port_get_proto(ports[i]); int low = semanage_port_get_low(ports[i]); int high = semanage_port_get_high(ports[i]); const char *proto_str = semanage_port_get_proto_str(proto); const char *proto_str2; int proto2, low2, high2; /* Find the first port with matching protocol to compare against */ do { if (j == nports - 1) goto next; j++; proto2 = semanage_port_get_proto(ports[j]); low2 = semanage_port_get_low(ports[j]); high2 = semanage_port_get_high(ports[j]); proto_str2 = semanage_port_get_proto_str(proto2); } while (proto != proto2); /* Overlap detected */ if (low2 <= high) { ERR(handle, "port overlap between ranges " "%u - %u (%s) <--> %u - %u (%s).", low, high, proto_str, low2, high2, proto_str2); goto invalid; } /* If closest port of matching protocol doesn't overlap with * test port, neither do the rest of them, because that's * how the sort function works on ports - lower bound * ports come first */ next: i++; j = i; } for (i = 0; i < nports; i++) semanage_port_free(ports[i]); free(ports); return STATUS_SUCCESS; err: ERR(handle, "could not complete ports validity check"); invalid: for (i = 0; i < nports; i++) semanage_port_free(ports[i]); free(ports); return STATUS_ERR; } libsemanage-2.3/src/ports_policy.c000066400000000000000000000026451233221606300173130ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_port; struct semanage_port_key; typedef struct semanage_port_key record_key_t; typedef struct semanage_port record_t; #define DBASE_RECORD_DEFINED #include "port_internal.h" #include "handle.h" #include "database.h" int semanage_port_query(semanage_handle_t * handle, const semanage_port_key_t * key, semanage_port_t ** response) { dbase_config_t *dconfig = semanage_port_dbase_policy(handle); return dbase_query(handle, dconfig, key, response); } int semanage_port_exists(semanage_handle_t * handle, const semanage_port_key_t * key, int *response) { dbase_config_t *dconfig = semanage_port_dbase_policy(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_port_count(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_port_dbase_policy(handle); return dbase_count(handle, dconfig, response); } int semanage_port_iterate(semanage_handle_t * handle, int (*handler) (const semanage_port_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_port_dbase_policy(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_port_list(semanage_handle_t * handle, semanage_port_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_port_dbase_policy(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-2.3/src/ports_policydb.c000066400000000000000000000041131233221606300176110ustar00rootroot00000000000000/* * Copyright (C) 2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_port; struct semanage_port_key; typedef struct semanage_port record_t; typedef struct semanage_port_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_policydb; typedef struct dbase_policydb dbase_t; #define DBASE_DEFINED #include #include #include "port_internal.h" #include "debug.h" #include "database_policydb.h" /* PORT RECORD (SEPOL): POLICYDB extension : method table */ record_policydb_table_t SEMANAGE_PORT_POLICYDB_RTABLE = { .add = NULL, .modify = (record_policydb_table_modify_t) sepol_port_modify, .set = NULL, .query = (record_policydb_table_query_t) sepol_port_query, .count = (record_policydb_table_count_t) sepol_port_count, .exists = (record_policydb_table_exists_t) sepol_port_exists, .iterate = (record_policydb_table_iterate_t) sepol_port_iterate, }; int port_policydb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig) { if (dbase_policydb_init(handle, "policy.kern", &SEMANAGE_PORT_RTABLE, &SEMANAGE_PORT_POLICYDB_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE; return STATUS_SUCCESS; } void port_policydb_dbase_release(dbase_config_t * dconfig) { dbase_policydb_release(dconfig->dbase); } libsemanage-2.3/src/pywrap-test.py000066400000000000000000001150521233221606300172670ustar00rootroot00000000000000#!/usr/bin/python import sys import getopt import semanage usage = "\ Choose one of the following tests:\n\ -m for modules\n\ -u for users\n\ -U for add user (warning this will write!)\n\ -s for seusers\n\ -S for add seuser (warning this will write!)\n\ -p for ports\n\ -P for add port (warning this will write!)\n\ -f for file contexts \n\ -F for add file context (warning this will write!)\n\ -i for network interfaces \n\ -I for add network interface (warning this will write!)\n\ -b for booleans \n\ -B for add boolean (warning this will write!)\n\ -c for aCtive booleans\n\ -C for set aCtive boolean (warning this will write!)\n\n\ -n for network nodes\n\ -N for add node (warning this will write!)\n\n\ Other options:\n\ -h for this help\n\ -v for verbose output\ " class Usage(Exception): def __init__(self, msg): Exception.__init__(self) self.msg = msg class Status(Exception): def __init__(self, msg): Exception.__init__(self) self.msg = msg class Error(Exception): def __init__(self, msg): Exception.__init__(self) self.msg = msg class Tests: def __init__(self): self.all = False self.users = False self.writeuser = False self.seusers = False self.writeseuser = False self.ports = False self.writeport = False self.fcontexts = False self.writefcontext = False self.interfaces = False self.writeinterface = False self.booleans = False self.writeboolean = False self.abooleans = False self.writeaboolean = False self.nodes = False self.writenode = False self.modules = False self.verbose = False def selected(self): return (self.all or self.users or self.modules or self.seusers or self.ports or self.fcontexts or self.interfaces or self.booleans or self.abooleans or self.writeuser or self.writeseuser or self.writeport or self.writefcontext or self.writeinterface or self.writeboolean or self.writeaboolean or self.nodes or self.writenode) def run(self, handle): if (self.users or self.all): self.test_users(handle) print "" if (self.seusers or self.all): self.test_seusers(handle) print "" if (self.ports or self.all): self.test_ports(handle) print "" if (self.modules or self.all): self.test_modules(handle) print "" if (self.fcontexts or self.all): self.test_fcontexts(handle) print "" if (self.interfaces or self.all): self.test_interfaces(handle) print "" if (self.booleans or self.all): self.test_booleans(handle) print "" if (self.abooleans or self.all): self.test_abooleans(handle) print "" if (self.nodes or self.all): self.test_nodes(handle) print "" if (self.writeuser or self.all): self.test_writeuser(handle) print "" if (self.writeseuser or self.all): self.test_writeseuser(handle) print "" if (self.writeport or self.all): self.test_writeport(handle) print "" if (self.writefcontext or self.all): self.test_writefcontext(handle) print "" if (self.writeinterface or self.all): self.test_writeinterface(handle) print "" if (self.writeboolean or self.all): self.test_writeboolean(handle) print "" if (self.writeaboolean or self.all): self.test_writeaboolean(handle) print "" if (self.writenode or self.all): self.test_writenode(handle) print "" def test_modules(self,sh): print "Testing modules..." (trans_cnt, mlist, mlist_size) = semanage.semanage_module_list(sh) print "Transaction number: ", trans_cnt print "Module list size: ", mlist_size if self.verbose: print "List reference: ", mlist if (mlist_size == 0): print "No modules installed!" print "This is not necessarily a test failure." return for idx in range(mlist_size): module = semanage.semanage_module_list_nth(mlist, idx) if self.verbose: print "Module reference: ", module print "Module name: ", semanage.semanage_module_get_name(module) print " Module version: ", semanage.semanage_module_get_version(module) def test_seusers(self,sh): print "Testing seusers..." (status, slist) = semanage.semanage_seuser_list(sh) if status < 0: raise Error("Could not list seusers") print "Query status (commit number): ", status if ( len(slist) == 0): print "No seusers found!" print "This is not necessarily a test failure." return for seuser in slist: if self.verbose: print "seseuser reference: ", seuser print "seuser name: ", semanage.semanage_seuser_get_name(seuser) print " seuser mls range: ", semanage.semanage_seuser_get_mlsrange(seuser) print " seuser sename: ", semanage.semanage_seuser_get_sename(seuser) semanage.semanage_seuser_free(seuser) def test_users(self,sh): print "Testing users..." (status, ulist) = semanage.semanage_user_list(sh) if status < 0: raise Error("Could not list users") print "Query status (commit number): ", status if ( len(ulist) == 0): print "No users found!" print "This is not necessarily a test failure." return for user in ulist: if self.verbose: print "User reference: ", user print "User name: ", semanage.semanage_user_get_name(user) print " User labeling prefix: ", semanage.semanage_user_get_prefix(user) print " User mls level: ", semanage.semanage_user_get_mlslevel(user) print " User mls range: ", semanage.semanage_user_get_mlsrange(user) print " User number of roles: ", semanage.semanage_user_get_num_roles(user) print " User roles: " (status, rlist) = semanage.semanage_user_get_roles(sh, user) if status < 0: raise Error("Could not get user roles") for role in rlist: print " ", role semanage.semanage_user_free(user) def test_ports(self,sh): print "Testing ports..." (status, plist) = semanage.semanage_port_list(sh) if status < 0: raise Error("Could not list ports") print "Query status (commit number): ", status if ( len(plist) == 0): print "No ports found!" print "This is not necessarily a test failure." return for port in plist: if self.verbose: print "Port reference: ", port low = semanage.semanage_port_get_low(port) high = semanage.semanage_port_get_high(port) con = semanage.semanage_port_get_con(port) proto = semanage.semanage_port_get_proto(port) proto_str = semanage.semanage_port_get_proto_str(proto) if low == high: range_str = str(low) else: range_str = str(low) + "-" + str(high) (rc, con_str) = semanage.semanage_context_to_string(sh,con) if rc < 0: con_str = "" print "Port: ", range_str, " ", proto_str, " Context: ", con_str semanage.semanage_port_free(port) def test_fcontexts(self,sh): print "Testing file contexts..." (status, flist) = semanage.semanage_fcontext_list(sh) if status < 0: raise Error("Could not list file contexts") print "Query status (commit number): ", status if (len(flist) == 0): print "No file contexts found!" print "This is not necessarily a test failure." return for fcon in flist: if self.verbose: print "File Context reference: ", fcon expr = semanage.semanage_fcontext_get_expr(fcon) type = semanage.semanage_fcontext_get_type(fcon) type_str = semanage.semanage_fcontext_get_type_str(type) con = semanage.semanage_fcontext_get_con(fcon) if not con: con_str = "<>" else: (rc, con_str) = semanage.semanage_context_to_string(sh,con) if rc < 0: con_str = "" print "File Expr: ", expr, " [", type_str, "] Context: ", con_str semanage.semanage_fcontext_free(fcon) def test_interfaces(self,sh): print "Testing network interfaces..." (status, ilist) = semanage.semanage_iface_list(sh) if status < 0: raise Error("Could not list interfaces") print "Query status (commit number): ", status if (len(ilist) == 0): print "No network interfaces found!" print "This is not necessarily a test failure." return for iface in ilist: if self.verbose: print "Interface reference: ", iface name = semanage.semanage_iface_get_name(iface) msg_con = semanage.semanage_iface_get_msgcon(iface) if_con = semanage.semanage_iface_get_ifcon(iface) (rc, msg_con_str) = semanage.semanage_context_to_string(sh,msg_con) if rc < 0: msg_con_str = "" (rc, if_con_str) = semanage.semanage_context_to_string(sh, if_con) if rc < 0: if_con_str = "" print "Interface: ", name, " Context: ", if_con_str, " Message Context: ", msg_con_str semanage.semanage_iface_free(iface) def test_booleans(self,sh): print "Testing booleans..." (status, blist) = semanage.semanage_bool_list(sh) if status < 0: raise Error("Could not list booleans") print "Query status (commit number): ", status if (len(blist) == 0): print "No booleans found!" print "This is not necessarily a test failure." return for pbool in blist: if self.verbose: print "Boolean reference: ", pbool name = semanage.semanage_bool_get_name(pbool) value = semanage.semanage_bool_get_value(pbool) print "Boolean: ", name, " Value: ", value semanage.semanage_bool_free(pbool) def test_abooleans(self,sh): print "Testing active booleans..." (status, ablist) = semanage.semanage_bool_list_active(sh) if status < 0: raise Error("Could not list active booleans") print "Query status (commit number): ", status if (len(ablist) == 0): print "No active booleans found!" print "This is not necessarily a test failure." return for abool in ablist: if self.verbose: print "Active boolean reference: ", abool name = semanage.semanage_bool_get_name(abool) value = semanage.semanage_bool_get_value(abool) print "Active Boolean: ", name, " Value: ", value semanage.semanage_bool_free(abool) def test_nodes(self,sh): print "Testing network nodes..." (status, nlist) = semanage.semanage_node_list(sh) if status < 0: raise Error("Could not list network nodes") print "Query status (commit number): ", status if (len(nlist) == 0): print "No network nodes found!" print "This is not necessarily a test failure." return for node in nlist: if self.verbose: print "Network node reference: ", node (status, addr) = semanage.semanage_node_get_addr(sh, node) if status < 0: addr = "" (status, mask) = semanage.semanage_node_get_mask(sh, node) if status < 0: mask = "" proto = semanage.semanage_node_get_proto(node) proto_str = semanage.semanage_node_get_proto_str(proto) con = semanage.semanage_node_get_con(node) (status, con_str) = semanage.semanage_context_to_string(sh, con) if status < 0: con_str = "" print "Network Node: ", addr, "/", mask, " (", proto_str, ")", "Context: ", con_str semanage.semanage_node_free(node) def test_writeuser(self,sh): print "Testing user write..." (status, user) = semanage.semanage_user_create(sh) if status < 0: raise Error("Could not create user object") if self.verbose: print "User object created" status = semanage.semanage_user_set_name(sh,user, "testPyUser") if status < 0: raise Error("Could not set user name") if self.verbose: print "User name set: ", semanage.semanage_user_get_name(user) status = semanage.semanage_user_add_role(sh, user, "user_r") if status < 0: raise Error("Could not add role") status = semanage.semanage_user_set_prefix(sh,user, "user") if status < 0: raise Error("Could not set labeling prefix") if self.verbose: print "User prefix set: ", semanage.semanage_user_get_prefix(user) status = semanage.semanage_user_set_mlsrange(sh, user, "s0") if status < 0: raise Error("Could not set MLS range") if self.verbose: print "User mlsrange: ", semanage.semanage_user_get_mlsrange(user) status = semanage.semanage_user_set_mlslevel(sh, user, "s0") if status < 0: raise Error("Could not set MLS level") if self.verbose: print "User mlslevel: ", semanage.semanage_user_get_mlslevel(user) (status,key) = semanage.semanage_user_key_extract(sh,user) if status < 0: raise Error("Could not extract user key") if self.verbose: print "User key extracted: ", key (status,exists) = semanage.semanage_user_exists_local(sh,key) if status < 0: raise Error("Could not check if user exists") if self.verbose: print "Exists status (commit number): ", status if exists: (status, old_user) = semanage.semanage_user_query_local(sh, key) if status < 0: raise Error("Could not query old user") if self.verbose: print "Query status (commit number): ", status print "Starting transaction.." status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") status = semanage.semanage_user_modify_local(sh,key,user) if status < 0: raise Error("Could not modify user") status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit test transaction") print "Commit status (transaction number): ", status status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") if not exists: print "Removing user..." status = semanage.semanage_user_del_local(sh, key) if status < 0: raise Error("Could not delete test user") if self.verbose: print "User delete: ", status else: print "Resetting user..." status = semanage.semanage_user_modify_local(sh, key, old_user) if status < 0: raise Error("Could not reset test user") if self.verbose: print "User modify: ", status status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print "Commit status (transaction number): ", status semanage.semanage_user_key_free(key) semanage.semanage_user_free(user) if exists: semanage.semanage_user_free(old_user) def test_writeseuser(self,sh): print "Testing seuser write..." (status, seuser) = semanage.semanage_seuser_create(sh) if status < 0: raise Error("Could not create SEUser object") if self.verbose: print "SEUser object created." status = semanage.semanage_seuser_set_name(sh,seuser, "testPySEUser") if status < 0: raise Error("Could not set name") if self.verbose: print "SEUser name set: ", semanage.semanage_seuser_get_name(seuser) status = semanage.semanage_seuser_set_sename(sh, seuser, "root") if status < 0: raise Error("Could not set sename") if self.verbose: print "SEUser seuser: ", semanage.semanage_seuser_get_sename(seuser) status = semanage.semanage_seuser_set_mlsrange(sh, seuser, "s0:c0.c255") if status < 0: raise Error("Could not set MLS range") if self.verbose: print "SEUser mlsrange: ", semanage.semanage_seuser_get_mlsrange(seuser) (status,key) = semanage.semanage_seuser_key_extract(sh,seuser) if status < 0: raise Error("Could not extract SEUser key") if self.verbose: print "SEUser key extracted: ", key (status,exists) = semanage.semanage_seuser_exists_local(sh,key) if status < 0: raise Error("Could not check if SEUser exists") if self.verbose: print "Exists status (commit number): ", status if exists: (status, old_seuser) = semanage.semanage_seuser_query_local(sh, key) if status < 0: raise Error("Could not query old SEUser") if self.verbose: print "Query status (commit number): ", status print "Starting transaction..." status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") status = semanage.semanage_seuser_modify_local(sh,key,seuser) if status < 0: raise Error("Could not modify SEUser") status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit test transaction") print "Commit status (transaction number): ", status status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") if not exists: print "Removing seuser..." status = semanage.semanage_seuser_del_local(sh, key) if status < 0: raise Error("Could not delete test SEUser") if self.verbose: print "Seuser delete: ", status else: print "Resetting seuser..." status = semanage.semanage_seuser_modify_local(sh, key, old_seuser) if status < 0: raise Error("Could not reset test SEUser") if self.verbose: print "Seuser modify: ", status status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print "Commit status (transaction number): ", status semanage.semanage_seuser_key_free(key) semanage.semanage_seuser_free(seuser) if exists: semanage.semanage_seuser_free(old_seuser) def test_writeport(self,sh): print "Testing port write..." (status, port) = semanage.semanage_port_create(sh) if status < 0: raise Error("Could not create SEPort object") if self.verbose: print "SEPort object created." semanage.semanage_port_set_range(port,150,200) low = semanage.semanage_port_get_low(port) high = semanage.semanage_port_get_high(port) if self.verbose: print "SEPort range set: ", low, "-", high semanage.semanage_port_set_proto(port, semanage.SEMANAGE_PROTO_TCP); if self.verbose: print "SEPort protocol set: ", \ semanage.semanage_port_get_proto_str(semanage.SEMANAGE_PROTO_TCP) (status, con) = semanage.semanage_context_create(sh) if status < 0: raise Error("Could not create SEContext object") if self.verbose: print "SEContext object created (for port)." status = semanage.semanage_context_set_user(sh, con, "system_u") if status < 0: raise Error("Could not set context user") if self.verbose: print "SEContext user: ", semanage.semanage_context_get_user(con) status = semanage.semanage_context_set_role(sh, con, "object_r") if status < 0: raise Error("Could not set context role") if self.verbose: print "SEContext role: ", semanage.semanage_context_get_role(con) status = semanage.semanage_context_set_type(sh, con, "http_port_t") if status < 0: raise Error("Could not set context type") if self.verbose: print "SEContext type: ", semanage.semanage_context_get_type(con) status = semanage.semanage_context_set_mls(sh, con, "s0:c0.c255") if status < 0: raise Error("Could not set context MLS fields") if self.verbose: print "SEContext mls: ", semanage.semanage_context_get_mls(con) status = semanage.semanage_port_set_con(sh, port, con) if status < 0: raise Error("Could not set SEPort context") if self.verbose: print "SEPort context set: ", con (status,key) = semanage.semanage_port_key_extract(sh,port) if status < 0: raise Error("Could not extract SEPort key") if self.verbose: print "SEPort key extracted: ", key (status,exists) = semanage.semanage_port_exists_local(sh,key) if status < 0: raise Error("Could not check if SEPort exists") if self.verbose: print "Exists status (commit number): ", status if exists: (status, old_port) = semanage.semanage_port_query_local(sh, key) if status < 0: raise Error("Could not query old SEPort") if self.verbose: print "Query status (commit number): ", status print "Starting transaction..." status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") status = semanage.semanage_port_modify_local(sh,key,port) if status < 0: raise Error("Could not modify SEPort") status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit test transaction") print "Commit status (transaction number): ", status status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") if not exists: print "Removing port range..." status = semanage.semanage_port_del_local(sh, key) if status < 0: raise Error("Could not delete test SEPort") if self.verbose: print "Port range delete: ", status else: print "Resetting port range..." status = semanage.semanage_port_modify_local(sh, key, old_port) if status < 0: raise Error("Could not reset test SEPort") if self.verbose: print "Port range modify: ", status status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print "Commit status (transaction number): ", status semanage.semanage_context_free(con) semanage.semanage_port_key_free(key) semanage.semanage_port_free(port) if exists: semanage.semanage_port_free(old_port) def test_writefcontext(self,sh): print "Testing file context write..." (status, fcon) = semanage.semanage_fcontext_create(sh) if status < 0: raise Error("Could not create SEFcontext object") if self.verbose: print "SEFcontext object created." status = semanage.semanage_fcontext_set_expr(sh, fcon, "/test/fcontext(/.*)?") if status < 0: raise Error("Could not set expression") if self.verbose: print "SEFContext expr set: ", semanage.semanage_fcontext_get_expr(fcon) semanage.semanage_fcontext_set_type(fcon, semanage.SEMANAGE_FCONTEXT_REG) if self.verbose: print "SEFContext type set: ", semanage.semanage_fcontext_get_type_str(fcon) (status, con) = semanage.semanage_context_create(sh) if status < 0: raise Error("Could not create SEContext object") if self.verbose: print "SEContext object created (for file context)." status = semanage.semanage_context_set_user(sh, con, "system_u") if status < 0: raise Error("Could not set context user") if self.verbose: print "SEContext user: ", semanage.semanage_context_get_user(con) status = semanage.semanage_context_set_role(sh, con, "object_r") if status < 0: raise Error("Could not set context role") if self.verbose: print "SEContext role: ", semanage.semanage_context_get_role(con) status = semanage.semanage_context_set_type(sh, con, "default_t") if status < 0: raise Error("Could not set context type") if self.verbose: print "SEContext type: ", semanage.semanage_context_get_type(con) status = semanage.semanage_context_set_mls(sh, con, "s0:c0.c255") if status < 0: raise Error("Could not set context MLS fields") if self.verbose: print "SEContext mls: ", semanage.semanage_context_get_mls(con) status = semanage.semanage_fcontext_set_con(sh, fcon, con) if status < 0: raise Error("Could not set SEFcontext context") if self.verbose: print "SEFcontext context set: ", con (status,key) = semanage.semanage_fcontext_key_extract(sh,fcon) if status < 0: raise Error("Could not extract SEFcontext key") if self.verbose: print "SEFcontext key extracted: ", key (status,exists) = semanage.semanage_fcontext_exists_local(sh,key) if status < 0: raise Error("Could not check if SEFcontext exists") if self.verbose: print "Exists status (commit number): ", status if exists: (status, old_fcontext) = semanage.semanage_fcontext_query_local(sh, key) if status < 0: raise Error("Could not query old SEFcontext") if self.verbose: print "Query status (commit number): ", status print "Starting transaction..." status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") status = semanage.semanage_fcontext_modify_local(sh,key,fcon) if status < 0: raise Error("Could not modify SEFcontext") status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit test transaction") print "Commit status (transaction number): ", status status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") if not exists: print "Removing file context..." status = semanage.semanage_fcontext_del_local(sh, key) if status < 0: raise Error("Could not delete test SEFcontext") if self.verbose: print "File context delete: ", status else: print "Resetting file context..." status = semanage.semanage_fcontext_modify_local(sh, key, old_fcontext) if status < 0: raise Error("Could not reset test FContext") if self.verbose: print "File context modify: ", status status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print "Commit status (transaction number): ", status semanage.semanage_context_free(con) semanage.semanage_fcontext_key_free(key) semanage.semanage_fcontext_free(fcon) if exists: semanage.semanage_fcontext_free(old_fcontext) def test_writeinterface(self,sh): print "Testing network interface write..." (status, iface) = semanage.semanage_iface_create(sh) if status < 0: raise Error("Could not create SEIface object") if self.verbose: print "SEIface object created." status = semanage.semanage_iface_set_name(sh, iface, "test_iface") if status < 0: raise Error("Could not set SEIface name") if self.verbose: print "SEIface name set: ", semanage.semanage_iface_get_name(iface) (status, con) = semanage.semanage_context_create(sh) if status < 0: raise Error("Could not create SEContext object") if self.verbose: print "SEContext object created (for network interface)" status = semanage.semanage_context_set_user(sh, con, "system_u") if status < 0: raise Error("Could not set interface context user") if self.verbose: print "SEContext user: ", semanage.semanage_context_get_user(con) status = semanage.semanage_context_set_role(sh, con, "object_r") if status < 0: raise Error("Could not set interface context role") if self.verbose: print "SEContext role: ", semanage.semanage_context_get_role(con) status = semanage.semanage_context_set_type(sh, con, "default_t") if status < 0: raise Error("Could not set interface context type") if self.verbose: print "SEContext type: ", semanage.semanage_context_get_type(con) status = semanage.semanage_context_set_mls(sh, con, "s0:c0.c255") if status < 0: raise Error("Could not set interface context MLS fields") if self.verbose: print "SEContext mls: ", semanage.semanage_context_get_mls(con) status = semanage.semanage_iface_set_ifcon(sh, iface, con) if status < 0: raise Error("Could not set SEIface interface context") if self.verbose: print "SEIface interface context set: ", con status = semanage.semanage_iface_set_msgcon(sh, iface, con) if status < 0: raise Error("Could not set SEIface message context") if self.verbose: print "SEIface message context set: ", con (status,key) = semanage.semanage_iface_key_extract(sh,iface) if status < 0: raise Error("Could not extract SEIface key") if self.verbose: print "SEIface key extracted: ", key (status,exists) = semanage.semanage_iface_exists_local(sh,key) if status < 0: raise Error("Could not check if SEIface exists") if self.verbose: print "Exists status (commit number): ", status if exists: (status, old_iface) = semanage.semanage_iface_query_local(sh, key) if status < 0: raise Error("Could not query old SEIface") if self.verbose: print "Query status (commit number): ", status print "Starting transaction..." status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not begin semanage transaction") status = semanage.semanage_iface_modify_local(sh,key,iface) if status < 0: raise Error("Could not modify SEIface") status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit test transaction") print "Commit status (transaction number): ", status status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not begin semanage transaction") if not exists: print "Removing interface..." status = semanage.semanage_iface_del_local(sh, key) if status < 0: raise Error("Could not delete test SEIface") if self.verbose: print "Interface delete: ", status else: print "Resetting interface..." status = semanage.semanage_iface_modify_local(sh, key, old_iface) if status < 0: raise Error("Could not reset test SEIface") if self.verbose: print "Interface modify: ", status status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print "Commit status (transaction number): ", status semanage.semanage_context_free(con) semanage.semanage_iface_key_free(key) semanage.semanage_iface_free(iface) if exists: semanage.semanage_iface_free(old_iface) def test_writeboolean(self,sh): print "Testing boolean write..." (status, pbool) = semanage.semanage_bool_create(sh) if status < 0: raise Error("Could not create SEBool object") if self.verbose: print "SEBool object created." status = semanage.semanage_bool_set_name(sh, pbool, "allow_execmem") if status < 0: raise Error("Could not set name") if self.verbose: print "SEBool name set: ", semanage.semanage_bool_get_name(pbool) semanage.semanage_bool_set_value(pbool, 0) if self.verbose: print "SEbool value set: ", semanage.semanage_bool_set_value(pbool) (status,key) = semanage.semanage_bool_key_extract(sh, pbool) if status < 0: raise Error("Could not extract SEBool key") if self.verbose: print "SEBool key extracted: ", key (status,exists) = semanage.semanage_bool_exists_local(sh,key) if status < 0: raise Error("Could not check if SEBool exists") if self.verbose: print "Exists status (commit number): ", status if exists: (status, old_bool) = semanage.semanage_bool_query_local(sh, key) if status < 0: raise Error("Could not query old SEBool") if self.verbose: print "Query status (commit number): ", status print "Starting transaction..." status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") status = semanage.semanage_bool_modify_local(sh, key, pbool) if status < 0: raise Error("Could not modify SEBool") status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit test transaction") print "Commit status (transaction number): ", status status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") if not exists: print "Removing boolean..." status = semanage.semanage_bool_del_local(sh, key) if status < 0: raise Error("Could not delete test SEBool") if self.verbose: print "Boolean delete: ", status else: print "Resetting boolean..." status = semanage.semanage_bool_modify_local(sh, key, old_bool) if status < 0: raise Error("Could not reset test SEBool") if self.verbose: print "Boolean modify: ", status status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print "Commit status (transaction number): ", status semanage.semanage_bool_key_free(key) semanage.semanage_bool_free(pbool) if exists: semanage.semanage_bool_free(old_bool) def test_writeaboolean(self,sh): print "Testing active boolean write..." (status, key) = semanage.semanage_bool_key_create(sh, "allow_execmem") if status < 0: raise Error("Could not create SEBool key") if self.verbose: print "SEBool key created: ", key (status, old_bool) = semanage.semanage_bool_query_active(sh, key) if status < 0: raise Error("Could not query old SEBool") if self.verbose: print "Query status (commit number): ", status (status, abool) = semanage.semanage_bool_create(sh) if status < 0: raise Error("Could not create SEBool object") if self.verbose: print "SEBool object created." status = semanage.semanage_bool_set_name(sh, abool, "allow_execmem") if status < 0: raise Error("Could not set name") if self.verbose: print "SEBool name set: ", semanage.semanage_bool_get_name(abool) semanage.semanage_bool_set_value(abool, 0) if self.verbose: print "SEbool value set: ", semanage.semanage_bool_set_value(abool) print "Starting transaction..." status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") status = semanage.semanage_bool_set_active(sh,key,abool) if status < 0: raise Error("Could not modify SEBool") status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit test transaction") print "Commit status (transaction number): ", status print "Resetting old active boolean..." status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") status = semanage.semanage_bool_set_active(sh, key,old_bool) if status < 0: raise Error("Could not reset test SEBool") if self.verbose: print "SEBool active reset: ", status status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print "Commit status (transaction number): ", status semanage.semanage_bool_key_free(key) semanage.semanage_bool_free(abool) semanage.semanage_bool_free(old_bool) def test_writenode(self,sh): print "Testing network node write..." (status, node) = semanage.semanage_node_create(sh) if status < 0: raise Error("Could not create SENode object") if self.verbose: print "SENode object created." status = semanage.semanage_node_set_addr(sh, node, semanage.SEMANAGE_PROTO_IP6, "ffee:dddd::bbbb") if status < 0: raise Error("Could not set SENode address") status = semanage.semanage_node_set_mask(sh, node, semanage.SEMANAGE_PROTO_IP6, "::ffff:ffff:abcd:0000") if status < 0: raise Error("Could not set SENode netmask") semanage.semanage_node_set_proto(node, semanage.SEMANAGE_PROTO_IP6); if self.verbose: print "SENode protocol set: ", \ semanage.semanage_node_get_proto_str(semanage.SEMANAGE_PROTO_IP6) (status, con) = semanage.semanage_context_create(sh) if status < 0: raise Error("Could not create SEContext object") if self.verbose: print "SEContext object created (for node)." status = semanage.semanage_context_set_user(sh, con, "system_u") if status < 0: raise Error("Could not set context user") if self.verbose: print "SEContext user: ", semanage.semanage_context_get_user(con) status = semanage.semanage_context_set_role(sh, con, "object_r") if status < 0: raise Error("Could not set context role") if self.verbose: print "SEContext role: ", semanage.semanage_context_get_role(con) status = semanage.semanage_context_set_type(sh, con, "lo_node_t") if status < 0: raise Error("Could not set context type") if self.verbose: print "SEContext type: ", semanage.semanage_context_get_type(con) status = semanage.semanage_context_set_mls(sh, con, "s0:c0.c255") if status < 0: raise Error("Could not set context MLS fields") if self.verbose: print "SEContext mls: ", semanage.semanage_context_get_mls(con) status = semanage.semanage_node_set_con(sh, node, con) if status < 0: raise Error("Could not set SENode context") if self.verbose: print "SENode context set: ", con (status,key) = semanage.semanage_node_key_extract(sh, node) if status < 0: raise Error("Could not extract SENode key") if self.verbose: print "SENode key extracted: ", key (status,exists) = semanage.semanage_node_exists_local(sh,key) if status < 0: raise Error("Could not check if SENode exists") if self.verbose: print "Exists status (commit number): ", status if exists: (status, old_node) = semanage.semanage_node_query_local(sh, key) if status < 0: raise Error("Could not query old SENode") if self.verbose: print "Query status (commit number): ", status print "Starting transaction..." status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") status = semanage.semanage_node_modify_local(sh,key, node) if status < 0: raise Error("Could not modify SENode") status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit test transaction") print "Commit status (transaction number): ", status status = semanage.semanage_begin_transaction(sh) if status < 0: raise Error("Could not start semanage transaction") if not exists: print "Removing network node..." status = semanage.semanage_node_del_local(sh, key) if status < 0: raise Error("Could not delete test SENode") if self.verbose: print "Network node delete: ", status else: print "Resetting network node..." status = semanage.semanage_node_modify_local(sh, key, old_node) if status < 0: raise Error("Could not reset test SENode") if self.verbose: print "Network node modify: ", status status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print "Commit status (transaction number): ", status semanage.semanage_context_free(con) semanage.semanage_node_key_free(key) semanage.semanage_node_free(node) if exists: semanage.semanage_node_free(old_node) def main(argv=None): if argv is None: argv = sys.argv try: try: opts, args = getopt.getopt(argv[1:], "hvmuspfibcUSPFIBCanN", ["help", "verbose", "modules", "users", "seusers", "ports", "file contexts", "network interfaces", "booleans", "active booleans", "network nodes", "writeuser", "writeseuser", "writeport", "writefcontext", "writeinterface", "writeboolean", "writeaboolean", "writenode", "all"]) tests = Tests() for o, a in opts: if o == "-v": tests.verbose = True print "Verbose output selected." if o == "-a": tests.all = True if o == "-u": tests.users = True if o == "-U": tests.writeuser = True if o == "-s": tests.seusers = True if o == "-S": tests.writeseuser = True if o == "-p": tests.ports = True if o == "-P": tests.writeport = True if o == "-f": tests.fcontexts = True if o == "-F": tests.writefcontext = True if o == "-i": tests.interfaces = True if o == "-I": tests.writeinterface = True if o == "-b": tests.booleans = True if o == "-B": tests.writeboolean = True if o == "-c": tests.abooleans = True if o == "-C": tests.writeaboolean = True if o == "-n": tests.nodes = True if o == "-N": tests.writenode = True if o == "-m": tests.modules = True if o == "-h": raise Usage(usage) if not tests.selected(): raise Usage("Please select a valid test.") except getopt.error, msg: raise Usage(msg) sh=semanage.semanage_handle_create() if (semanage.semanage_is_managed(sh) != 1): raise Status("Unmanaged!") status = semanage.semanage_connect(sh) if status < 0: raise Error("Could not establish semanage connection") tests.run(sh) status = semanage.semanage_disconnect(sh) if status < 0: raise Error("Could not disconnect") semanage.semanage_handle_destroy(sh) except Usage, err: print >>sys.stderr, err.msg except Status, err: print >>sys.stderr, err.msg except Error, err: print >>sys.stderr, err.msg return 2 if __name__ == "__main__": sys.exit(main()) libsemanage-2.3/src/semanage.conf000066400000000000000000000033301233221606300170400ustar00rootroot00000000000000# Authors: Jason Tang # # Copyright (C) 2004-2005 Tresys Technology, LLC # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # Specify how libsemanage will interact with a SELinux policy manager. # The four options are: # # "source" - libsemanage manipulates a source SELinux policy # "direct" - libsemanage will write directly to a module store. # /foo/bar - Write by way of a policy management server, whose # named socket is at /foo/bar. The path must begin # with a '/'. # foo.com:4242 - Establish a TCP connection to a remote policy # management server at foo.com. If there is a colon # then the remainder is interpreted as a port number; # otherwise default to port 4242. module-store = direct # When generating the final linked and expanded policy, by default # semanage will set the policy version to POLICYDB_VERSION_MAX, as # given in . Change this setting if a different # version is necessary. #policy-version = 19 libsemanage-2.3/src/semanage_conf.h000066400000000000000000000041611233221606300173520ustar00rootroot00000000000000/* Authors: Jason Tang * * Copyright (C) 2004-2005 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SEMANAGE_CONF_H #define SEMANAGE_CONF_H #include #include #include /* libsemanage has its own configuration file. It has two main parts: * - single options * - external programs to execute whenever a policy is to be loaded */ typedef struct semanage_conf { enum semanage_connect_type store_type; char *store_path; /* used for both socket path and policy dir */ int server_port; int policyvers; /* version for server generated policies */ int expand_check; int save_previous; int save_linked; int disable_genhomedircon; int usepasswd; int handle_unknown; mode_t file_mode; int bzip_blocksize; int bzip_small; char *ignoredirs; /* ";" separated of list for genhomedircon to ignore */ struct external_prog *load_policy; struct external_prog *setfiles; struct external_prog *sefcontext_compile; struct external_prog *mod_prog, *linked_prog, *kernel_prog; } semanage_conf_t; /* A linked list of verification programs. Each one is called in * order of appearance within the configuration file. */ typedef struct external_prog { char *path; char *args; struct external_prog *next; } external_prog_t; semanage_conf_t *semanage_conf_parse(const char *config_filename); void semanage_conf_destroy(semanage_conf_t * conf); #endif libsemanage-2.3/src/semanage_store.c000066400000000000000000002127411233221606300175610ustar00rootroot00000000000000/* Authors: Karl MacMillan * Joshua Brindle * Jason Tang * Christopher Ashworth * Chris PeBenito * * Copyright (C) 2004-2006 Tresys Technology, LLC * Copyright (C) 2005 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* This file contains semanage routines that manipulate the files on a * local module store. Sandbox routines, used by both source and * direct connections, are here as well. */ struct dbase_policydb; typedef struct dbase_policydb dbase_t; #define DBASE_DEFINED #include "semanage_store.h" #include "database_policydb.h" #include "handle.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "debug.h" static const char *DISABLESTR="disabled"; #define SEMANAGE_CONF_FILE "semanage.conf" /* relative path names to enum semanage_paths to special files and * directories for the module store */ #define TRUE 1 enum semanage_file_defs { SEMANAGE_ROOT, SEMANAGE_TRANS_LOCK, SEMANAGE_READ_LOCK, SEMANAGE_NUM_FILES }; static char *semanage_paths[SEMANAGE_NUM_STORES][SEMANAGE_STORE_NUM_PATHS]; static char *semanage_files[SEMANAGE_NUM_FILES] = { NULL }; static char *semanage_conf; static int semanage_paths_initialized = 0; /* These are paths relative to the bottom of the module store */ static const char *semanage_relative_files[SEMANAGE_NUM_FILES] = { "", "/semanage.trans.LOCK", "/semanage.read.LOCK" }; static const char *semanage_store_paths[SEMANAGE_NUM_STORES] = { "/active", "/previous", "/tmp" }; /* this is the module store path relative to semanage_policy_root() */ #define SEMANAGE_MOD_DIR "/modules" /* relative path names to enum sandbox_paths for special files within * a sandbox */ static const char *semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = { "", "/modules", "/policy.kern", "/base.pp", "/base.linked", "/file_contexts", "/homedir_template", "/file_contexts.template", "/commit_num", "/ports.local", "/interfaces.local", "/nodes.local", "/booleans.local", "/file_contexts.local", "/seusers", "/users.local", "/users_extra.local", "/seusers.final", "/users_extra", "/netfilter_contexts", "/file_contexts.homedirs", "/disable_dontaudit", "/preserve_tunables", }; /* A node used in a linked list of file contexts; used for sorting. */ typedef struct semanage_file_context_node { char *path; char *file_type; char *context; int path_len; int effective_len; int type_len; int context_len; int meta; /* position of first meta char in path, -1 if none */ struct semanage_file_context_node *next; } semanage_file_context_node_t; /* A node used in a linked list of buckets that contain * semanage_file_context_node lists. Used for sorting. */ typedef struct semanage_file_context_bucket { semanage_file_context_node_t *data; struct semanage_file_context_bucket *next; } semanage_file_context_bucket_t; /* A node used in a linked list of netfilter rules. */ typedef struct semanage_netfilter_context_node { char *rule; size_t rule_len; struct semanage_netfilter_context_node *next; } semanage_netfilter_context_node_t; /* Initialize the paths to config file, lock files and store root. */ static int semanage_init_paths(const char *root) { size_t len, prefix_len; int i; if (!root) return -1; prefix_len = (strlen(root) + strlen(SEMANAGE_MOD_DIR)); for (i = 0; i < SEMANAGE_NUM_FILES; i++) { len = (strlen(semanage_relative_files[i]) + prefix_len); semanage_files[i] = calloc(len + 1, sizeof(char)); if (!semanage_files[i]) return -1; sprintf(semanage_files[i], "%s%s%s", root, SEMANAGE_MOD_DIR, semanage_relative_files[i]); } len = strlen(semanage_selinux_path()) + strlen(SEMANAGE_CONF_FILE); semanage_conf = calloc(len + 1, sizeof(char)); if (!semanage_conf) return -1; snprintf(semanage_conf, len, "%s%s", semanage_selinux_path(), SEMANAGE_CONF_FILE); return 0; } /* This initializes the paths inside the stores, this is only necessary * when directly accessing the store */ static int semanage_init_store_paths(const char *root) { int i, j; size_t len; size_t prefix_len; char *prefix; if (!root) return -1; prefix_len = (strlen(root) + strlen(SEMANAGE_MOD_DIR)); prefix = calloc(prefix_len + 1, sizeof(char)); if (!prefix) return -1; sprintf(prefix, "%s%s", root, SEMANAGE_MOD_DIR); for (i = 0; i < SEMANAGE_NUM_STORES; i++) { for (j = 0; j < SEMANAGE_STORE_NUM_PATHS; j++) { len = prefix_len + strlen(semanage_store_paths[i]) + strlen(semanage_sandbox_paths[j]); semanage_paths[i][j] = calloc(len + 1, sizeof(char)); if (!semanage_paths[i][j]) goto cleanup; sprintf(semanage_paths[i][j], "%s%s%s", prefix, semanage_store_paths[i], semanage_sandbox_paths[j]); } } cleanup: free(prefix); return 0; } /* THIS MUST BE THE FIRST FUNCTION CALLED IN THIS LIBRARY. If the * library has nnot been initialized yet then call the functions that * initialize the path variables. This function does nothing if it * was previously called and that call was successful. Return 0 on * success, -1 on error. * * Note that this function is NOT thread-safe. */ int semanage_check_init(const char *root) { int rc; if (semanage_paths_initialized == 0) { rc = semanage_init_paths(root); if (rc) return rc; rc = semanage_init_store_paths(root); if (rc) return rc; semanage_paths_initialized = 1; } return 0; } /* Given a definition number, return a file name from the paths array */ const char *semanage_fname(enum semanage_sandbox_defs file_enum) { return semanage_sandbox_paths[file_enum]; } /* Given a store location (active/previous/tmp) and a definition * number, return a fully-qualified path to that file or directory. * The caller must not alter the string returned (and hence why this * function return type is const). * * This function shall never return a NULL, assuming that * semanage_check_init() was previously called. */ const char *semanage_path(enum semanage_store_defs store, enum semanage_sandbox_defs path_name) { assert(semanage_paths[store][path_name]); return semanage_paths[store][path_name]; } /**************** functions that create module store ***************/ /* Check that the semanage store exists. If 'create' is non-zero then * create the directories. Returns 0 if module store exists (either * already or just created), -1 if does not exist or could not be * read, or -2 if it could not create the store. */ int semanage_create_store(semanage_handle_t * sh, int create) { struct stat sb; int mode_mask = R_OK | W_OK | X_OK; const char *path = semanage_files[SEMANAGE_ROOT]; int fd; if (stat(path, &sb) == -1) { if (errno == ENOENT && create) { if (mkdir(path, S_IRWXU) == -1) { ERR(sh, "Could not create module store at %s.", path); return -2; } } else { if (create) ERR(sh, "Could not read from module store at %s.", path); return -1; } } else { if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) { ERR(sh, "Could not access module store at %s, or it is not a directory.", path); return -1; } } path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL); if (stat(path, &sb) == -1) { if (errno == ENOENT && create) { if (mkdir(path, S_IRWXU) == -1) { ERR(sh, "Could not create module store, active subdirectory at %s.", path); return -2; } } else { ERR(sh, "Could not read from module store, active subdirectory at %s.", path); return -1; } } else { if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) { ERR(sh, "Could not access module store active subdirectory at %s, or it is not a directory.", path); return -1; } } path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_MODULES); if (stat(path, &sb) == -1) { if (errno == ENOENT && create) { if (mkdir(path, S_IRWXU) == -1) { ERR(sh, "Could not create module store, active modules subdirectory at %s.", path); return -2; } } else { ERR(sh, "Could not read from module store, active modules subdirectory at %s.", path); return -1; } } else { if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) { ERR(sh, "Could not access module store active modules subdirectory at %s, or it is not a directory.", path); return -1; } } path = semanage_files[SEMANAGE_READ_LOCK]; if (stat(path, &sb) == -1) { if (errno == ENOENT && create) { if ((fd = creat(path, S_IRUSR | S_IWUSR)) == -1) { ERR(sh, "Could not create lock file at %s.", path); return -2; } close(fd); } else { ERR(sh, "Could not read lock file at %s.", path); return -1; } } else { if (!S_ISREG(sb.st_mode) || access(path, R_OK | W_OK) == -1) { ERR(sh, "Could not access lock file at %s.", path); return -1; } } return 0; } /* returns <0 if the active store cannot be read or doesn't exist * 0 if the store exists but the lock file cannot be accessed * SEMANAGE_CAN_READ if the store can be read and the lock file used * SEMANAGE_CAN_WRITE if the modules directory and binary policy dir can be written to */ int semanage_store_access_check(void) { const char *path; int rc = -1; /* read access on active store */ path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL); if (access(path, R_OK | X_OK) != 0) goto out; /* we can read the active store meaning it is managed * so now we return 0 to indicate no error */ rc = 0; /* read access on lock file required for locking * write access necessary if the lock file does not exist */ path = semanage_files[SEMANAGE_READ_LOCK]; if (access(path, R_OK) != 0) { if (access(path, F_OK) == 0) { goto out; } path = semanage_files[SEMANAGE_ROOT]; if (access(path, R_OK | W_OK | X_OK) != 0) { goto out; } } /* everything needed for reading has been checked */ rc = SEMANAGE_CAN_READ; /* check the modules directory */ path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_MODULES); if (access(path, R_OK | W_OK | X_OK) != 0) goto out; rc = SEMANAGE_CAN_WRITE; out: return rc; } /********************* other I/O functions *********************/ static int is_disabled_file(const char *file) { char *ptr = strrchr(file, '.'); if (! ptr) return 0; ptr++; return (strcmp(ptr, DISABLESTR) == 0); } /* Callback used by scandir() to select files. */ static int semanage_filename_select(const struct dirent *d) { if (d->d_name[0] == '.' && (d->d_name[1] == '\0' || (d->d_name[1] == '.' && d->d_name[2] == '\0'))) return 0; return 1; } int semanage_disable_module(const char *file) { char path[PATH_MAX]; int in; int n = snprintf(path, PATH_MAX, "%s.%s", file, DISABLESTR); if (n < 0 || n >= PATH_MAX) return -1; if ((in = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) == -1) { return -1; } close(in); return 0; } int semanage_enable_module(const char *file) { char path[PATH_MAX]; int n = snprintf(path, PATH_MAX, "%s.%s", file, DISABLESTR); if (n < 0 || n >= PATH_MAX) return -1; if ((unlink(path) < 0) && (errno != ENOENT)) return -1; return 0; } int semanage_module_enabled(const char *file) { char path[PATH_MAX]; if (is_disabled_file(file)) return 0; int n = snprintf(path, PATH_MAX, "%s.%s", file, DISABLESTR); if (n < 0 || n >= PATH_MAX) return 1; return (access(path, F_OK ) != 0); } /* Callback used by scandir() to select module files. */ static int semanage_modulename_select(const struct dirent *d) { if (d->d_name[0] == '.' && (d->d_name[1] == '\0' || (d->d_name[1] == '.' && d->d_name[2] == '\0'))) return 0; return (! is_disabled_file(d->d_name)); } /* Copies a file from src to dst. If dst already exists then * overwrite it. Returns 0 on success, -1 on error. */ static int semanage_copy_file(const char *src, const char *dst, mode_t mode) { int in, out, retval = 0, amount_read, n, errsv = errno; char tmp[PATH_MAX]; char buf[4192]; mode_t mask; n = snprintf(tmp, PATH_MAX, "%s.tmp", dst); if (n < 0 || n >= PATH_MAX) return -1; if ((in = open(src, O_RDONLY)) == -1) { return -1; } if (!mode) mode = S_IRUSR | S_IWUSR; mask = umask(0); if ((out = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, mode)) == -1) { umask(mask); errsv = errno; close(in); retval = -1; goto out; } umask(mask); while (retval == 0 && (amount_read = read(in, buf, sizeof(buf))) > 0) { if (write(out, buf, amount_read) < 0) { errsv = errno; retval = -1; } } if (amount_read < 0) { errsv = errno; retval = -1; } close(in); if (close(out) < 0) { errsv = errno; retval = -1; } if (!retval && rename(tmp, dst) == -1) return -1; out: errno = errsv; return retval; } /* Copies all of the files from src to dst, recursing into * subdirectories. Returns 0 on success, -1 on error. */ static int semanage_copy_dir(const char *src, const char *dst) { int i, len = 0, retval = -1; struct stat sb; struct dirent **names = NULL; char path[PATH_MAX], path2[PATH_MAX]; if ((len = scandir(src, &names, semanage_filename_select, NULL)) == -1) { return -1; } for (i = 0; i < len; i++) { snprintf(path, sizeof(path), "%s/%s", src, names[i]->d_name); /* stat() to see if this entry is a file or not since * d_type isn't set properly on XFS */ if (stat(path, &sb)) { goto cleanup; } snprintf(path2, sizeof(path2), "%s/%s", dst, names[i]->d_name); if (S_ISDIR(sb.st_mode)) { if (mkdir(path2, 0700) == -1 || semanage_copy_dir(path, path2) == -1) { goto cleanup; } } else if (S_ISREG(sb.st_mode)) { if (semanage_copy_file(path, path2, sb.st_mode) == -1) { goto cleanup; } } } retval = 0; cleanup: for (i = 0; names != NULL && i < len; i++) { free(names[i]); } free(names); return retval; } /* Recursively removes the contents of a directory along with the * directory itself. Returns 0 on success, non-zero on error. */ int semanage_remove_directory(const char *path) { struct dirent **namelist = NULL; int num_entries, i; if ((num_entries = scandir(path, &namelist, semanage_filename_select, NULL)) == -1) { return -1; } for (i = 0; i < num_entries; i++) { char s[NAME_MAX]; struct stat buf; snprintf(s, sizeof(s), "%s/%s", path, namelist[i]->d_name); if (stat(s, &buf) == -1) { return -2; } if (S_ISDIR(buf.st_mode)) { int retval; if ((retval = semanage_remove_directory(s)) != 0) { return retval; } } else { if (remove(s) == -1) { return -3; } } free(namelist[i]); } free(namelist); if (rmdir(path) == -1) { return -4; } return 0; } /********************* sandbox management routines *********************/ /* Creates a sandbox for a single client. Returns 0 if a * sandbox was created, -1 on error. */ int semanage_make_sandbox(semanage_handle_t * sh) { const char *sandbox = semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL); struct stat buf; int errsv; if (stat(sandbox, &buf) == -1) { if (errno != ENOENT) { ERR(sh, "Error scanning directory %s.", sandbox); return -1; } errno = 0; } else { /* remove the old sandbox */ if (semanage_remove_directory(sandbox) != 0) { ERR(sh, "Error removing old sandbox directory %s.", sandbox); return -1; } } if (mkdir(sandbox, S_IRWXU) == -1 || semanage_copy_dir(semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL), sandbox) == -1) { ERR(sh, "Could not copy files to sandbox %s.", sandbox); goto cleanup; } return 0; cleanup: errsv = errno; semanage_remove_directory(sandbox); errno = errsv; return -1; } static int semanage_get_modules_names_filter(semanage_handle_t * sh, char ***filenames, int *len, int (*filter)(const struct dirent *)) { const char *modules_path; struct dirent **namelist = NULL; int num_files, i, retval = -1; if (sh->is_in_transaction) { modules_path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES); } else { modules_path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_MODULES); } *filenames = NULL; *len = 0; if ((num_files = scandir(modules_path, &namelist, filter, alphasort)) == -1) { ERR(sh, "Error while scanning directory %s.", modules_path); goto cleanup; } if (num_files == 0) { retval = 0; goto cleanup; } if ((*filenames = (char **)calloc(num_files, sizeof(**filenames))) == NULL) { ERR(sh, "Out of memory!"); goto cleanup; } for (i = 0; i < num_files; i++) { char *filename; char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s/%s", modules_path, namelist[i]->d_name); if ((filename = strdup(path)) == NULL) { int j; ERR(sh, "Out of memory!"); for (j = 0; j < i; j++) { free((*filenames)[j]); } free(*filenames); *filenames = NULL; goto cleanup; } (*filenames)[i] = filename; } *len = num_files; retval = 0; cleanup: for (i = 0; i < num_files; i++) { free(namelist[i]); } free(namelist); return retval; } /* Scans the modules directory for the current semanage handler. This * might be the active directory or sandbox, depending upon if the * handler has a transaction lock. Allocates and fills in *filenames * with an array of module filenames; length of array is stored in * *len. The caller is responsible for free()ing *filenames and its * individual elements. Upon success returns 0, -1 on error. */ int semanage_get_modules_names(semanage_handle_t * sh, char ***filenames, int *len) { return semanage_get_modules_names_filter(sh, filenames, len, semanage_modulename_select); } /* Scans the modules directory for the current semanage handler. This * might be the active directory or sandbox, depending upon if the * handler has a transaction lock. Allocates and fills in *filenames * with an array of module filenames; length of array is stored in * *len. The caller is responsible for free()ing *filenames and its * individual elements. Upon success returns 0, -1 on error. */ int semanage_get_active_modules_names(semanage_handle_t * sh, char ***filenames, int *len) { int rc = semanage_get_modules_names_filter(sh, filenames, len, semanage_modulename_select); if ( rc != 0 ) return rc; int i = 0, num_modules = *len; char **names=*filenames; while ( i < num_modules ) { if (! semanage_module_enabled(names[i])) { free(names[i]); names[i]=names[num_modules-1]; names[num_modules-1] = NULL; num_modules--; } i++; } *len = num_modules; return 0; } /******************* routines that run external programs *******************/ /* Appends a single character to a string. Returns a pointer to the * realloc()ated string. If out of memory return NULL; original * string will remain untouched. */ static char *append(char *s, char c) { size_t len = (s == NULL ? 0 : strlen(s)); char *new_s = realloc(s, len + 2); if (new_s == NULL) { return NULL; } s = new_s; s[len] = c; s[len + 1] = '\0'; return s; } /* Append string 't' to string 's', realloc()ating 's' as needed. 't' * may be safely free()d afterwards. Returns a pointer to the * realloc()ated 's'. If out of memory return NULL; original strings * will remain untouched. */ static char *append_str(char *s, const char *t) { size_t s_len = (s == NULL ? 0 : strlen(s)); size_t t_len = (t == NULL ? 0 : strlen(t)); char *new_s = realloc(s, s_len + t_len + 1); if (new_s == NULL) { return NULL; } s = new_s; memcpy(s + s_len, t, t_len); s[s_len + t_len] = '\0'; return s; } /* * Append an argument string to an argument vector. Replaces the * argument pointer passed in. Returns -1 on error. Increments * 'num_args' on success. */ static int append_arg(char ***argv, int *num_args, const char *arg) { char **a; a = realloc(*argv, sizeof(**argv) * (*num_args + 1)); if (a == NULL) return -1; *argv = a; a[*num_args] = NULL; if (arg) { a[*num_args] = strdup(arg); if (!a[*num_args]) return -1; } (*num_args)++; return 0; } /* free()s all strings within a null-terminated argument vector, as * well as the pointer itself. */ static void free_argv(char **argv) { int i; for (i = 0; argv != NULL && argv[i] != NULL; i++) { free(argv[i]); } free(argv); } /* Take an argument string and split and place into an argument * vector. Respect normal quoting, double-quoting, and backslash * conventions. Perform substitutions on $@ and $< symbols. Returns * a NULL-terminated argument vector; caller is responsible for * free()ing the vector and its elements. */ static char **split_args(const char *arg0, char *arg_string, const char *new_name, const char *old_name) { char **argv = NULL, *s, *arg = NULL, *targ; int num_args = 0, in_quote = 0, in_dquote = 0, rc; rc = append_arg(&argv, &num_args, arg0); if (rc) goto cleanup; s = arg_string; /* parse the argument string one character at a time, * repsecting quotes and other special characters */ while (s != NULL && *s != '\0') { switch (*s) { case '\\':{ if (*(s + 1) == '\0') { targ = append(arg, '\\'); if (targ == NULL) goto cleanup; arg = targ; } else { targ = append(arg, *(s + 1)); if (targ == NULL) goto cleanup; arg = targ; s++; } break; } case '\'':{ if (in_dquote) { targ = append(arg, *s); if (targ == NULL) goto cleanup; arg = targ; } else if (in_quote) { in_quote = 0; } else { in_quote = 1; targ = append(arg, '\0'); if (targ == NULL) goto cleanup; arg = targ; } break; } case '\"':{ if (in_quote) { targ = append(arg, *s); if (targ == NULL) goto cleanup; arg = targ; } else if (in_dquote) { in_dquote = 0; } else { in_dquote = 1; targ = append(arg, '\0'); if (targ == NULL) goto cleanup; arg = targ; } break; } case '$':{ switch (*(s + 1)) { case '@':{ targ = append_str(arg, new_name); if (targ == NULL) goto cleanup; arg = targ; s++; break; } case '<':{ targ = append_str(arg, old_name); if (targ == NULL) goto cleanup; arg = targ; s++; break; } default:{ targ = append(arg, *s); if (targ == NULL) goto cleanup; arg = targ; } } break; } default:{ if (isspace(*s) && !in_quote && !in_dquote) { if (arg != NULL) { rc = append_arg(&argv, &num_args, arg); free(arg); arg = NULL; } } else { if ((targ = append(arg, *s)) == NULL) { goto cleanup; } else { arg = targ; } } } } s++; } if (arg != NULL) { rc = append_arg(&argv, &num_args, arg); free(arg); arg = NULL; } /* explicitly add a NULL at the end */ rc = append_arg(&argv, &num_args, NULL); if (rc) goto cleanup; return argv; cleanup: free_argv(argv); free(arg); return NULL; } /* Take the arguments given in v->args and expand any $ macros within. * Split the arguments into different strings (argv). Next fork and * execute the process. BE SURE THAT ALL FILE DESCRIPTORS ARE SET TO * CLOSE-ON-EXEC. Take the return value of the child process and * return it, -1 on error. */ static int semanage_exec_prog(semanage_handle_t * sh, external_prog_t * e, const char *new_name, const char *old_name) { char **argv; pid_t forkval; int status = 0; argv = split_args(e->path, e->args, new_name, old_name); if (argv == NULL) { ERR(sh, "Out of memory!"); return -1; } /* no need to use pthread_atfork() -- child will not be using * any mutexes. */ forkval = vfork(); if (forkval == 0) { /* child process. file descriptors will be closed * because they were set as close-on-exec. */ execve(e->path, argv, NULL); _exit(EXIT_FAILURE); /* if execve() failed */ } free_argv(argv); if (forkval == -1) { ERR(sh, "Error while forking process."); return -1; } /* parent process. wait for child to finish */ if (waitpid(forkval, &status, 0) == -1 || !WIFEXITED(status)) { ERR(sh, "Child process %s did not exit cleanly.", e->path); return -1; } return WEXITSTATUS(status); } /* reloads the policy pointed to by the handle, used locally by install * and exported for user reload requests */ int semanage_reload_policy(semanage_handle_t * sh) { int r = 0; if (!sh) return -1; if ((r = semanage_exec_prog(sh, sh->conf->load_policy, "", "")) != 0) { ERR(sh, "load_policy returned error code %d.", r); } return r; } hidden_def(semanage_reload_policy) /* This expands the file_context.tmpl file to file_context and homedirs.template */ int semanage_split_fc(semanage_handle_t * sh) { FILE *file_con = NULL; int fc = -1, hd = -1, retval = -1; char buf[PATH_MAX] = { 0 }; /* I use fopen here instead of open so that I can use fgets which only reads a single line */ file_con = fopen(semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL), "r"); if (!file_con) { ERR(sh, "Could not open %s for reading.", semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL)); goto cleanup; } fc = open(semanage_path(SEMANAGE_TMP, SEMANAGE_FC), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (!fc) { ERR(sh, "Could not open %s for writing.", semanage_path(SEMANAGE_TMP, SEMANAGE_FC)); goto cleanup; } hd = open(semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (hd < 0) { ERR(sh, "Could not open %s for writing.", semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL)); goto cleanup; } while (fgets_unlocked(buf, PATH_MAX, file_con)) { if (!strncmp(buf, "HOME_DIR", 8) || !strncmp(buf, "HOME_ROOT", 9) || strstr(buf, "ROLE") || strstr(buf, "USER")) { /* This contains one of the template variables, write it to homedir.template */ if (write(hd, buf, strlen(buf)) < 0) { ERR(sh, "Write to %s failed.", semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL)); goto cleanup; } } else { if (write(fc, buf, strlen(buf)) < 0) { ERR(sh, "Write to %s failed.", semanage_path(SEMANAGE_TMP, SEMANAGE_FC)); goto cleanup; } } } retval = 0; cleanup: if (file_con) fclose(file_con); if (fc >= 0) close(fc); if (hd >= 0) close(hd); return retval; } static int sefcontext_compile(semanage_handle_t * sh, const char *path) { int r; if ((r = semanage_exec_prog(sh, sh->conf->sefcontext_compile, path, "")) != 0) { ERR(sh, "sefcontext_compile returned error code %d. Compiling %s", r, path); return -1; } return 0; } /* Actually load the contents of the current active directory into the * kernel. Return 0 on success, -3 on error. */ static int semanage_install_active(semanage_handle_t * sh) { int retval = -3, r, len; char *storepath = NULL; struct stat astore, istore; const char *active_kernel = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_KERNEL); const char *active_fc = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_FC); const char *active_fc_loc = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_FC_LOCAL); const char *active_seusers = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_SEUSERS); const char *active_nc = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_NC); const char *active_fc_hd = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_FC_HOMEDIRS); const char *running_fc = semanage_file_context_path(); const char *running_fc_loc = semanage_file_context_local_path(); const char *running_fc_hd = semanage_file_context_homedir_path(); const char *running_hd = semanage_homedir_context_path(); const char *running_policy = semanage_binary_policy_path(); const char *running_seusers = semanage_usersconf_path(); const char *running_nc = semanage_netfilter_context_path(); const char *really_active_store = semanage_policy_root(); /* This is very unelegant, the right thing to do is export the path * building code in libselinux so that you can get paths for a given * POLICYTYPE and should probably be done in the future. */ char store_fc[PATH_MAX]; char store_fc_loc[PATH_MAX]; char store_pol[PATH_MAX]; char store_seusers[PATH_MAX]; char store_nc[PATH_MAX]; char store_fc_hd[PATH_MAX]; len = strlen(really_active_store); running_fc += len; running_fc_loc += len; running_fc_hd += len; running_hd += len; running_policy += len; running_seusers += len; running_nc += len; if (asprintf(&storepath, "%s%s", semanage_selinux_path(), sh->conf->store_path) < 0) return retval; snprintf(store_pol, PATH_MAX, "%s%s.%d", storepath, running_policy, sh->conf->policyvers); if (semanage_copy_file(active_kernel, store_pol, sh->conf->file_mode) == -1) { ERR(sh, "Could not copy %s to %s.", active_kernel, store_pol); goto cleanup; } if (!sh->conf->disable_genhomedircon) { snprintf(store_fc_hd, PATH_MAX, "%s%s", storepath, running_fc_hd); if (semanage_copy_file(active_fc_hd, store_fc_hd, sh->conf->file_mode) == -1) { ERR(sh, "Could not copy %s to %s.", active_fc_hd, store_fc_hd); goto cleanup; } } snprintf(store_fc, PATH_MAX, "%s%s", storepath, running_fc); if (semanage_copy_file(active_fc, store_fc, sh->conf->file_mode) == -1) { ERR(sh, "Could not copy %s to %s.", active_fc, store_fc); goto cleanup; } snprintf(store_fc_loc, PATH_MAX, "%s%s", storepath, running_fc_loc); if (semanage_copy_file(active_fc_loc, store_fc_loc, sh->conf->file_mode) == -1 && errno != ENOENT) { ERR(sh, "Could not copy %s to %s.", active_fc_loc, store_fc_loc); goto cleanup; } errno = 0; snprintf(store_seusers, PATH_MAX, "%s%s", storepath, running_seusers); if (semanage_copy_file (active_seusers, store_seusers, sh->conf->file_mode) == -1 && errno != ENOENT) { ERR(sh, "Could not copy %s to %s.", active_seusers, store_seusers); goto cleanup; } errno = 0; snprintf(store_nc, PATH_MAX, "%s%s", storepath, running_nc); if (semanage_copy_file(active_nc, store_nc, sh->conf->file_mode) == -1 && errno != ENOENT) { ERR(sh, "Could not copy %s to %s.", active_nc, store_nc); goto cleanup; } errno = 0; if (!sh->do_reload) goto skip_reload; /* This stats what libselinux says the active store is (according to config) * and what we are installing to, to decide if they are the same store. If * they are not then we do not reload policy */ if (stat(really_active_store, &astore) == 0) { if (stat(storepath, &istore)) { ERR(sh, "Could not stat store path %s.", storepath); goto cleanup; } if (!(astore.st_ino == istore.st_ino && astore.st_dev == istore.st_dev)) { /* They are not the same store */ goto skip_reload; } } else if (errno == ENOENT && strcmp(really_active_store, storepath) != 0) { errno = 0; goto skip_reload; } if (semanage_reload_policy(sh)) { goto cleanup; } skip_reload: if (sh->do_check_contexts && (r = semanage_exec_prog(sh, sh->conf->setfiles, store_pol, store_fc)) != 0) { ERR(sh, "setfiles returned error code %d.", r); goto cleanup; } if (sefcontext_compile(sh, store_fc) != 0) { goto cleanup; } if (sefcontext_compile(sh, store_fc_loc) != 0) { goto cleanup; } if (sefcontext_compile(sh, store_fc_hd) != 0) { goto cleanup; } retval = 0; cleanup: (void) unlink(active_kernel); if (symlink(store_pol, active_kernel) < 0) { ERR(sh, "Unable to create sybolic link from %s to %s error code %d.", active_kernel, store_pol, r); } free(storepath); return retval; } /* Prepare the sandbox to be installed by making a backup of the * current active directory. Then copy the sandbox to the active * directory. Return the new commit number on success, negative * values on error. */ static int semanage_commit_sandbox(semanage_handle_t * sh) { int commit_number, fd, retval; char write_buf[32]; const char *commit_filename = semanage_path(SEMANAGE_TMP, SEMANAGE_COMMIT_NUM_FILE); ssize_t amount_written; const char *active = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL); const char *backup = semanage_path(SEMANAGE_PREVIOUS, SEMANAGE_TOPLEVEL); const char *sandbox = semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL); struct stat buf; /* update the commit number */ if ((commit_number = semanage_direct_get_serial(sh)) < 0) { return -1; } commit_number++; memset(write_buf, 0, sizeof(write_buf)); snprintf(write_buf, sizeof(write_buf), "%d", commit_number); if ((fd = open(commit_filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) { ERR(sh, "Could not open commit number file %s for writing.", commit_filename); return -1; } amount_written = write(fd, write_buf, sizeof(write_buf)); if (amount_written == -1) { ERR(sh, "Error while writing commit number to %s.", commit_filename); close(fd); return -1; } close(fd); retval = commit_number; if (semanage_get_active_lock(sh) < 0) { return -1; } /* make the backup of the current active directory */ if (stat(backup, &buf) == 0) { if (S_ISDIR(buf.st_mode) && semanage_remove_directory(backup) != 0) { ERR(sh, "Could not remove previous backup %s.", backup); retval = -1; goto cleanup; } } else if (errno != ENOENT) { ERR(sh, "Could not stat directory %s.", backup); retval = -1; goto cleanup; } if (rename(active, backup) == -1) { ERR(sh, "Error while renaming %s to %s.", active, backup); retval = -1; goto cleanup; } /* clean up some files from the sandbox before install */ /* remove homedir_template from sandbox */ if (rename(sandbox, active) == -1) { ERR(sh, "Error while renaming %s to %s.", sandbox, active); /* note that if an error occurs during the next * function then the store will be left in an * inconsistent state */ if (rename(backup, active) < 0) ERR(sh, "Error while renaming %s back to %s.", backup, active); retval = -1; goto cleanup; } if (semanage_install_active(sh) != 0) { /* note that if an error occurs during the next three * function then the store will be left in an * inconsistent state */ int errsv = errno; if (rename(active, sandbox) < 0) ERR(sh, "Error while renaming %s back to %s.", active, sandbox); else if (rename(backup, active) < 0) ERR(sh, "Error while renaming %s back to %s.", backup, active); else semanage_install_active(sh); errno = errsv; retval = -1; goto cleanup; } if (!sh->conf->save_previous) { int errsv = errno; retval = semanage_remove_directory(backup); if (retval < 0) { ERR(sh, "Could not delete previous directory %s.", backup); goto cleanup; } errno = errsv; } cleanup: semanage_release_active_lock(sh); return retval; } /* Takes the kernel policy in a sandbox, move it to the active * directory, copy it to the binary policy path, then load it. Upon * error move the active directory back to the sandbox. This function * should be placed within a mutex lock to ensure that it runs * atomically. Returns commit number on success, -1 on error. */ int semanage_install_sandbox(semanage_handle_t * sh) { int retval = -1, commit_num = -1; if (sh->conf->load_policy == NULL) { ERR(sh, "No load_policy program specified in configuration file."); goto cleanup; } if (sh->conf->setfiles == NULL) { ERR(sh, "No setfiles program specified in configuration file."); goto cleanup; } if (sh->conf->sefcontext_compile == NULL) { ERR(sh, "No sefcontext_compile program specified in configuration file."); goto cleanup; } if ((commit_num = semanage_commit_sandbox(sh)) < 0) { retval = commit_num; goto cleanup; } retval = commit_num; cleanup: return retval; } /********************* functions that manipulate lock *********************/ static int semanage_get_lock(semanage_handle_t * sh, const char *lock_name, const char *lock_file) { int fd; struct timeval origtime, curtime; int got_lock = 0; if ((fd = open(lock_file, O_RDONLY)) == -1) { if ((fd = open(lock_file, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) { ERR(sh, "Could not open direct %s at %s.", lock_name, lock_file); return -1; } } if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { ERR(sh, "Could not set close-on-exec for %s at %s.", lock_name, lock_file); close(fd); return -1; } if (sh->timeout == 0) { /* return immediately */ origtime.tv_sec = 0; } else { origtime.tv_sec = sh->timeout; } origtime.tv_usec = 0; do { curtime.tv_sec = 1; curtime.tv_usec = 0; if (flock(fd, LOCK_EX | LOCK_NB) == 0) { got_lock = 1; break; } else if (errno != EAGAIN) { ERR(sh, "Error obtaining direct %s at %s.", lock_name, lock_file); close(fd); return -1; } if (origtime.tv_sec > 0 || sh->timeout == -1) { if (select(0, NULL, NULL, NULL, &curtime) == -1) { if (errno == EINTR) { continue; } ERR(sh, "Error while waiting to get direct %s at %s.", lock_name, lock_file); close(fd); return -1; } origtime.tv_sec--; } } while (origtime.tv_sec > 0 || sh->timeout == -1); if (!got_lock) { ERR(sh, "Could not get direct %s at %s.", lock_name, lock_file); close(fd); return -1; } return fd; } /* Locking for the module store for transactions. This is very basic * locking of the module store and doesn't do anything if the module * store is being manipulated with a program not using this library * (but the policy should prevent that). Returns 0 on success, -1 if * it could not obtain a lock. */ int semanage_get_trans_lock(semanage_handle_t * sh) { const char *lock_file = semanage_files[SEMANAGE_TRANS_LOCK]; if (sh->u.direct.translock_file_fd >= 0) return 0; sh->u.direct.translock_file_fd = semanage_get_lock(sh, "transaction lock", lock_file); if (sh->u.direct.translock_file_fd >= 0) { return 0; } else { return -1; } } /* Locking for the module store for active store reading; this also includes * the file containing the commit number. This is very basic locking * of the module store and doesn't do anything if the module store is * being manipulated with a program not using this library (but the * policy should prevent that). Returns 0 on success, -1 if it could * not obtain a lock. */ int semanage_get_active_lock(semanage_handle_t * sh) { const char *lock_file = semanage_files[SEMANAGE_READ_LOCK]; if (sh->u.direct.activelock_file_fd >= 0) return 0; sh->u.direct.activelock_file_fd = semanage_get_lock(sh, "read lock", lock_file); if (sh->u.direct.activelock_file_fd >= 0) { return 0; } else { return -1; } } /* Releases the transaction lock. Does nothing if there was not one already * there. */ void semanage_release_trans_lock(semanage_handle_t * sh) { int errsv = errno; if (sh->u.direct.translock_file_fd >= 0) { flock(sh->u.direct.translock_file_fd, LOCK_UN); close(sh->u.direct.translock_file_fd); sh->u.direct.translock_file_fd = -1; } errno = errsv; } /* Releases the read lock. Does nothing if there was not one already * there. */ void semanage_release_active_lock(semanage_handle_t * sh) { int errsv = errno; if (sh->u.direct.activelock_file_fd >= 0) { flock(sh->u.direct.activelock_file_fd, LOCK_UN); close(sh->u.direct.activelock_file_fd); sh->u.direct.activelock_file_fd = -1; } errno = errsv; } /* Read the current commit number from the commit number file which * the handle is pointing, resetting the file pointer afterwards. * Return it (a non-negative number), or -1 on error. */ int semanage_direct_get_serial(semanage_handle_t * sh) { char buf[32]; int fd, commit_number; ssize_t amount_read; const char *commit_filename; memset(buf, 0, sizeof(buf)); if (sh->is_in_transaction) { commit_filename = semanage_path(SEMANAGE_TMP, SEMANAGE_COMMIT_NUM_FILE); } else { commit_filename = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_COMMIT_NUM_FILE); } if ((fd = open(commit_filename, O_RDONLY)) == -1) { if (errno == ENOENT) { /* the commit number file does not exist yet, * so assume that the number is 0 */ errno = 0; return 0; } else { ERR(sh, "Could not open commit number file %s.", commit_filename); return -1; } } amount_read = read(fd, buf, sizeof(buf)); if (amount_read == -1) { ERR(sh, "Error while reading commit number from %s.", commit_filename); commit_number = -1; } else if (sscanf(buf, "%d", &commit_number) != 1) { /* if nothing was read, assume that the commit number is 0 */ commit_number = 0; } else if (commit_number < 0) { /* read file ought never have negative values */ ERR(sh, "Commit number file %s is corrupted; it should only contain a non-negative integer.", commit_filename); commit_number = -1; } close(fd); return commit_number; } /* HIGHER LEVEL COMMIT FUNCTIONS */ /* Loads a module (or a base) from a fully-qualified 'filename' into a * newly allocated sepol_module_package_t structure and returns it in * '*package'. Caller is responsible for destroying it afterwards via * sepol_module_package_destroy(). Returns 0 on success, -1 on error. */ static int semanage_load_module(semanage_handle_t * sh, const char *filename, sepol_module_package_t ** package) { int retval = 0; FILE *fp; struct sepol_policy_file *pf = NULL; *package = NULL; if (sepol_module_package_create(package) == -1) { ERR(sh, "Out of memory!"); return -1; } if (sepol_policy_file_create(&pf)) { ERR(sh, "Out of memory!"); goto cleanup; } if ((fp = fopen(filename, "rb")) == NULL) { ERR(sh, "Could not open module file %s for reading.", filename); goto cleanup; } ssize_t size; char *data = NULL; if ((size = bunzip(sh, fp, &data)) > 0) { sepol_policy_file_set_mem(pf, data, size); } else { rewind(fp); __fsetlocking(fp, FSETLOCKING_BYCALLER); sepol_policy_file_set_fp(pf, fp); } sepol_policy_file_set_handle(pf, sh->sepolh); if (sepol_module_package_read(*package, pf, 0) == -1) { ERR(sh, "Error while reading from module file %s.", filename); fclose(fp); free(data); goto cleanup; } sepol_policy_file_free(pf); fclose(fp); free(data); return retval; cleanup: sepol_module_package_free(*package); *package = NULL; sepol_policy_file_free(pf); return -1; } /* Links all of the modules within the sandbox into the base module. * '*base' will point to the module package that contains everything * linked together (caller must call sepol_module_package_destroy() on * it afterwards). '*mods' will be a list of module packages and * '*num_modules' will be the number of elements within '*mods' * (caller must destroy each element as well as the pointer itself.) * Both '*base' and '*mods' will be set to NULL upon entering this * function. Returns 0 on success, -1 on error. */ int semanage_link_sandbox(semanage_handle_t * sh, sepol_module_package_t ** base) { const char *base_filename = NULL; char **module_filenames = NULL; int retval = -1, i; int num_modules = 0; sepol_module_package_t **mods = NULL; *base = NULL; /* first make sure that base module is readable */ if ((base_filename = semanage_path(SEMANAGE_TMP, SEMANAGE_BASE)) == NULL) { goto cleanup; } if (access(base_filename, R_OK) == -1) { ERR(sh, "Could not access sandbox base file %s.", base_filename); goto cleanup; } /* get list of modules and load them */ if (semanage_get_active_modules_names(sh, &module_filenames, &num_modules) == -1 || semanage_load_module(sh, base_filename, base) == -1) { goto cleanup; } if ((mods = calloc(num_modules, sizeof(*mods))) == NULL) { ERR(sh, "Out of memory!"); num_modules = 0; goto cleanup; } for (i = 0; i < num_modules; i++) { if (semanage_load_module(sh, module_filenames[i], mods + i) == -1) { goto cleanup; } } if (sepol_link_packages(sh->sepolh, *base, mods, num_modules, 0) != 0) { ERR(sh, "Link packages failed"); goto cleanup; } retval = 0; cleanup: for (i = 0; module_filenames != NULL && i < num_modules; i++) { free(module_filenames[i]); } free(module_filenames); for (i = 0; mods != NULL && i < num_modules; i++) { sepol_module_package_free(mods[i]); } free(mods); return retval; } /* Links only the base module within the sandbox into the base module. * '*base' will point to the module package that contains everything * linked together (caller must call sepol_module_package_destroy() on * it afterwards). '*base' will be set to NULL upon entering this * function. Returns 0 on success, -1 on error. */ int semanage_link_base(semanage_handle_t * sh, sepol_module_package_t ** base) { const char *base_filename = NULL; int retval = -1; *base = NULL; /* first make sure that base module is readable */ if ((base_filename = semanage_path(SEMANAGE_TMP, SEMANAGE_BASE)) == NULL) { goto cleanup; } if (access(base_filename, R_OK) == -1) { ERR(sh, "Could not access sandbox base file %s.", base_filename); goto cleanup; } if (semanage_load_module(sh, base_filename, base) == -1) { goto cleanup; } retval = 0; cleanup: return retval; } /* * Expands the policy contained within *base */ int semanage_expand_sandbox(semanage_handle_t * sh, sepol_module_package_t * base, sepol_policydb_t ** policydb) { struct sepol_policydb *out = NULL; int policyvers = sh->conf->policyvers; int expand_check = sh->conf->expand_check ? sh->modules_modified : 0; if (sepol_policydb_create(&out)) goto err; sepol_set_expand_consume_base(sh->sepolh, 1); if (sepol_expand_module(sh->sepolh, sepol_module_package_get_policy(base), out, 0, expand_check) == -1) { ERR(sh, "Expand module failed"); goto err; } if (sepol_policydb_set_vers(out, policyvers)) { ERR(sh, "Unknown/Invalid policy version %d.", policyvers); goto err; } if (sh->conf->handle_unknown >= 0) sepol_policydb_set_handle_unknown(out, sh->conf->handle_unknown); *policydb = out; return STATUS_SUCCESS; err: sepol_policydb_free(out); return STATUS_ERR; } /** * Read the policy from the sandbox (kernel) */ int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in) { int retval = STATUS_ERR; const char *kernel_filename = NULL; struct sepol_policy_file *pf = NULL; FILE *infile = NULL; if ((kernel_filename = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_KERNEL)) == NULL) { goto cleanup; } if ((infile = fopen(kernel_filename, "r")) == NULL) { ERR(sh, "Could not open kernel policy %s for reading.", kernel_filename); goto cleanup; } __fsetlocking(infile, FSETLOCKING_BYCALLER); if (sepol_policy_file_create(&pf)) { ERR(sh, "Out of memory!"); goto cleanup; } sepol_policy_file_set_fp(pf, infile); sepol_policy_file_set_handle(pf, sh->sepolh); if (sepol_policydb_read(in, pf) == -1) { ERR(sh, "Error while reading kernel policy from %s.", kernel_filename); goto cleanup; } retval = STATUS_SUCCESS; cleanup: if (infile != NULL) { fclose(infile); } sepol_policy_file_free(pf); return retval; } /** * Writes the final policy to the sandbox (kernel) */ int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out) { int retval = STATUS_ERR; const char *kernel_filename = NULL; struct sepol_policy_file *pf = NULL; FILE *outfile = NULL; if ((kernel_filename = semanage_path(SEMANAGE_TMP, SEMANAGE_KERNEL)) == NULL) { goto cleanup; } if ((outfile = fopen(kernel_filename, "wb")) == NULL) { ERR(sh, "Could not open kernel policy %s for writing.", kernel_filename); goto cleanup; } __fsetlocking(outfile, FSETLOCKING_BYCALLER); if (sepol_policy_file_create(&pf)) { ERR(sh, "Out of memory!"); goto cleanup; } sepol_policy_file_set_fp(pf, outfile); sepol_policy_file_set_handle(pf, sh->sepolh); if (sepol_policydb_write(out, pf) == -1) { ERR(sh, "Error while writing kernel policy to %s.", kernel_filename); goto cleanup; } retval = STATUS_SUCCESS; cleanup: if (outfile != NULL) { fclose(outfile); } sepol_policy_file_free(pf); return retval; } /* Execute the module verification programs for each source module. * Returns 0 if every verifier returned success, -1 on error. */ int semanage_verify_modules(semanage_handle_t * sh, char **module_filenames, int num_modules) { int i, retval; semanage_conf_t *conf = sh->conf; if (conf->mod_prog == NULL) { return 0; } for (i = 0; i < num_modules; i++) { char *module = module_filenames[i]; external_prog_t *e; for (e = conf->mod_prog; e != NULL; e = e->next) { if ((retval = semanage_exec_prog(sh, e, module, "$<")) != 0) { return -1; } } } return 0; } /* Execute the linker verification programs for the linked (but not * expanded) base. Returns 0 if every verifier returned success, -1 * on error. */ int semanage_verify_linked(semanage_handle_t * sh) { external_prog_t *e; semanage_conf_t *conf = sh->conf; const char *linked_filename = semanage_path(SEMANAGE_TMP, SEMANAGE_LINKED); int retval = -1; if (conf->linked_prog == NULL) { return 0; } for (e = conf->linked_prog; e != NULL; e = e->next) { if (semanage_exec_prog(sh, e, linked_filename, "$<") != 0) { goto cleanup; } } retval = 0; cleanup: return retval; } /* Execute each of the kernel verification programs. Returns 0 if * every verifier returned success, -1 on error. */ int semanage_verify_kernel(semanage_handle_t * sh) { int retval = -1; const char *kernel_filename = semanage_path(SEMANAGE_TMP, SEMANAGE_KERNEL); semanage_conf_t *conf = sh->conf; external_prog_t *e; if (conf->kernel_prog == NULL) { return 0; } for (e = conf->kernel_prog; e != NULL; e = e->next) { if (semanage_exec_prog(sh, e, kernel_filename, "$<") != 0) { goto cleanup; } } retval = 0; cleanup: return retval; } /********************* functions that sort file contexts *********************/ /* Free the given node. */ static void semanage_fc_node_destroy(semanage_file_context_node_t * x) { free(x->path); free(x->file_type); free(x->context); free(x); } /* Free the linked list of nodes starting at the given node. */ static void semanage_fc_node_list_destroy(semanage_file_context_node_t * x) { semanage_file_context_node_t *temp; while (x) { temp = x; x = x->next; semanage_fc_node_destroy(temp); } } /* Free the linked list of buckets (and their node lists) * starting at the given bucket. */ static void semanage_fc_bucket_list_destroy(semanage_file_context_bucket_t * x) { semanage_file_context_bucket_t *temp; while (x) { temp = x; x = x->next; semanage_fc_node_list_destroy(temp->data); free(temp); } } /* Compares two file contexts' regular expressions and returns: * -1 if a is less specific than b * 0 if a and be are equally specific * 1 if a is more specific than b * The comparison is based on the following heuristics, * in order from most important to least important, given a and b: * If a is a regular expression and b is not, * -> a is less specific than b. * If a's stem length is shorter than b's stem length, * -> a is less specific than b. * If a's string length is shorter than b's string length, * -> a is less specific than b. * If a does not have a specified type and b does not, * -> a is less specific than b. * FIXME: These heuristics are imperfect, but good enough for * now. A proper comparison would determine which (if either) * regular expression is a subset of the other. */ static int semanage_fc_compare(semanage_file_context_node_t * a, semanage_file_context_node_t * b) { int a_has_meta = (a->meta >= 0); int b_has_meta = (b->meta >= 0); /* Check to see if either a or b are regexes * and the other isn't. */ if (a_has_meta && !b_has_meta) return -1; if (b_has_meta && !a_has_meta) return 1; /* Check to see if either a or b have a shorter stem * length than the other. */ if (a->meta < b->meta) return -1; if (b->meta < a->meta) return 1; /* Check to see if either a or b have a shorter string * length than the other. */ if (a->effective_len < b->effective_len) return -1; if (b->effective_len < a->effective_len) return 1; /* Check to see if either a or b has a specified type * and the other doesn't. */ if (!a->file_type && b->file_type) return -1; if (!b->file_type && a->file_type) return 1; /* If none of the above conditions were satisfied, * then a and b are equally specific. */ return 0; } /* Merges two sorted file context linked lists into a single sorted one. * The left list is assumed to represent nodes that came first in the original ordering. * The final sorted list is returned. */ static semanage_file_context_node_t * semanage_fc_merge(semanage_file_context_node_t * left, semanage_file_context_node_t * right) { semanage_file_context_node_t *head; semanage_file_context_node_t *current; semanage_file_context_node_t *tail; if (!left) return right; if (!right) return left; if (semanage_fc_compare(left, right) == 1) { head = tail = right; right = right->next; } else { head = tail = left; left = left->next; } while (left && right) { /* if left was more specific than right, * insert right before left. Otherwise leave order alone. */ if (semanage_fc_compare(left, right) == 1) { current = right; right = right->next; } else { current = left; left = left->next; } tail = tail->next = current; } tail->next = (left != NULL) ? left : right; return head; } /* Sorts file contexts from least specific to most specific. * A bucket linked list is passed in. Upon completion, * there is only one bucket (pointed to by master) that * contains a linked list of all the file contexts in sorted order. * Explanation of the algorithm: * This is a stable implementation of an iterative merge sort. * Each bucket initially has a linked list of file contexts * that are 1 node long. * Each pass, buckets (and the nodes they contain) are merged * two at time. * Buckets are merged until there is only one bucket left, * containing the list of file contexts, sorted. */ static void semanage_fc_merge_sort(semanage_file_context_bucket_t * master) { semanage_file_context_bucket_t *current; semanage_file_context_bucket_t *temp; /* Loop until master is the only bucket left. * When we stop master contains the sorted list. */ while (master->next) { current = master; /* Merge buckets two-by-two. * If there is an odd number of buckets, the last * bucket will be left alone, which corresponds * to the operation of merging it with an empty bucket. */ while (current) { if (current->next) { current->data = semanage_fc_merge(current->data, current->next->data); temp = current->next; current->next = current->next->next; /* Free the (now empty) second bucket. * (This does not touch the node list * in the bucket because it has been * shifted over to the first bucket. */ free(temp); } current = current->next; } } } /* Compute the location of the first regular expression * meta character in the path of the given node, if it exists. * On return: * fc_node->meta = position of meta character, if it exists * (-1 corresponds to no character) */ static void semanage_fc_find_meta(semanage_file_context_node_t * fc_node) { int c = 0; int escape_chars = 0; fc_node->meta = -1; /* Note: this while loop has been adapted from * spec_hasMetaChars in matchpathcon.c from * libselinux-1.22. */ while (fc_node->path[c] != '\0') { switch (fc_node->path[c]) { case '.': case '^': case '$': case '?': case '*': case '+': case '|': case '[': case '(': case '{': fc_node->meta = c - escape_chars; return; case '\\': /* If an escape character is found, * skip the next character. */ c++; escape_chars++; break; } c++; } } /* Replicates strchr, but limits search to buf_len characters. */ static char *semanage_strnchr(const char *buf, size_t buf_len, char c) { size_t idx = 0; if (buf == NULL) return NULL; if (buf_len <= 0) return NULL; while (idx < buf_len) { if (buf[idx] == c) return (char *)buf + idx; idx++; } return NULL; } /* Returns a pointer to the end of line character in the given buffer. * Used in the context of a file context char buffer that we will be * parsing and sorting. */ static char *semanage_get_line_end(const char *buf, size_t buf_len) { char *line_end = NULL; if (buf == NULL) return NULL; if (buf_len <= 0) return NULL; line_end = semanage_strnchr(buf, buf_len, '\n'); if (!line_end) line_end = semanage_strnchr(buf, buf_len, '\r'); if (!line_end) line_end = semanage_strnchr(buf, buf_len, EOF); return line_end; } /* Entry function for sorting a set of file context lines. * Returns 0 on success, -1 on failure. * Allocates a buffer pointed to by sorted_buf that contains the sorted lines. * sorted_buf_len is set to the size of this buffer. * This buffer is guaranteed to have a final \0 character. * This buffer must be released by the caller. */ int semanage_fc_sort(semanage_handle_t * sh, const char *buf, size_t buf_len, char **sorted_buf, size_t * sorted_buf_len) { size_t start, finish, regex_len, type_len, context_len; size_t line_len, buf_remainder, i; ssize_t sanity_check; const char *line_buf, *line_end; char *sorted_buf_pos; int escape_chars, just_saw_escape; semanage_file_context_node_t *temp; semanage_file_context_node_t *head; semanage_file_context_node_t *current; semanage_file_context_bucket_t *master; semanage_file_context_bucket_t *bcurrent; i = 0; if (sh == NULL) { return -1; } if (buf == NULL) { ERR(sh, "Received NULL buffer."); return -1; } if (buf_len <= 0) { ERR(sh, "Received buffer of length 0."); return -1; } /* Initialize the head of the linked list * that will contain a node for each file context line. */ head = current = (semanage_file_context_node_t *) calloc(1, sizeof (semanage_file_context_node_t)); if (!head) { ERR(sh, "Failure allocating memory."); return -1; } /* Parse the char buffer into a semanage_file_context_node_t linked list. */ line_buf = buf; buf_remainder = buf_len; while ((line_end = semanage_get_line_end(line_buf, buf_remainder))) { line_len = line_end - line_buf + 1; sanity_check = buf_remainder - line_len; buf_remainder = buf_remainder - line_len; if (sanity_check < 0) { ERR(sh, "Failure parsing file context buffer."); semanage_fc_node_list_destroy(head); return -1; } if (line_len == 0 || line_len == 1) { line_buf = line_end + 1; continue; } /* Skip the whitespace at the front of the line. */ for (i = 0; i < line_len; i++) { if (!isspace(line_buf[i])) break; } /* Check for a blank line. */ if (i >= line_len) { line_buf = line_end + 1; continue; } /* Check if the line is a comment. */ if (line_buf[i] == '#') { line_buf = line_end + 1; continue; } /* Allocate a new node. */ temp = (semanage_file_context_node_t *) calloc(1, sizeof (semanage_file_context_node_t)); if (!temp) { ERR(sh, "Failure allocating memory."); semanage_fc_node_list_destroy(head); return -1; } temp->next = NULL; /* Extract the regular expression from the line. */ escape_chars = 0; just_saw_escape = 0; start = i; while (i < line_len && (!isspace(line_buf[i]))) { if (line_buf[i] == '\\') { if (!just_saw_escape) { escape_chars++; just_saw_escape = 1; } else { /* We're looking at an escaped escape. Reset our flag. */ just_saw_escape = 0; } } else { just_saw_escape = 0; } i++; } finish = i; regex_len = finish - start; if (regex_len == 0) { ERR(sh, "WARNING: semanage_fc_sort: Regex of length 0."); semanage_fc_node_destroy(temp); line_buf = line_end + 1; continue; } temp->path = (char *)strndup(&line_buf[start], regex_len); if (!temp->path) { ERR(sh, "Failure allocating memory."); semanage_fc_node_destroy(temp); semanage_fc_node_list_destroy(head); return -1; } /* Skip the whitespace after the regular expression. */ for (; i < line_len; i++) { if (!isspace(line_buf[i])) break; } if (i == line_len) { ERR(sh, "WARNING: semanage_fc_sort: Incomplete context. %s", temp->path); semanage_fc_node_destroy(temp); line_buf = line_end + 1; continue; } /* Extract the inode type from the line (if it exists). */ if (line_buf[i] == '-') { type_len = 2; /* defined as '--', '-d', '-f', etc. */ if (i + type_len >= line_len) { ERR(sh, "WARNING: semanage_fc_sort: Incomplete context. %s", temp->path); semanage_fc_node_destroy(temp); line_buf = line_end + 1; continue; } /* Record the inode type. */ temp->file_type = (char *)strndup(&line_buf[i], type_len); if (!temp->file_type) { ERR(sh, "Failure allocating memory."); semanage_fc_node_destroy(temp); semanage_fc_node_list_destroy(head); return -1; } i += type_len; /* Skip the whitespace after the type. */ for (; i < line_len; i++) { if (!isspace(line_buf[i])) break; } if (i == line_len) { ERR(sh, "WARNING: semanage_fc_sort: Incomplete context. %s", temp->path); semanage_fc_node_destroy(temp); line_buf = line_end + 1; continue; } } else { type_len = 0; /* inode type did not exist in the file context */ } /* Extract the context from the line. */ start = i; while (i < line_len && (!isspace(line_buf[i]))) i++; finish = i; context_len = finish - start; temp->context = (char *)strndup(&line_buf[start], context_len); if (!temp->context) { ERR(sh, "Failure allocating memory."); semanage_fc_node_destroy(temp); semanage_fc_node_list_destroy(head); return -1; } /* Initialize the data about the file context. */ temp->path_len = regex_len; temp->effective_len = regex_len - escape_chars; temp->type_len = type_len; temp->context_len = context_len; semanage_fc_find_meta(temp); /* Add this node to the end of the linked list. */ current->next = temp; current = current->next; line_buf = line_end + 1; } /* Create the bucket linked list from the node linked list. */ current = head->next; bcurrent = master = (semanage_file_context_bucket_t *) calloc(1, sizeof(semanage_file_context_bucket_t)); if (!master) { ERR(sh, "Failure allocating memory."); semanage_fc_node_list_destroy(head); return -1; } /* Free the head node, as it is no longer used. */ semanage_fc_node_destroy(head); head = NULL; /* Place each node into a bucket. */ while (current) { bcurrent->data = current; current = current->next; /* Detach the node in the bucket from the old list. */ bcurrent->data->next = NULL; /* If we need another bucket, add one to the end. */ if (current) { bcurrent->next = (semanage_file_context_bucket_t *) calloc(1, sizeof(semanage_file_context_bucket_t)); if (!(bcurrent->next)) { ERR(sh, "Failure allocating memory."); semanage_fc_bucket_list_destroy(master); return -1; } bcurrent = bcurrent->next; } } /* Sort the bucket list. */ semanage_fc_merge_sort(master); /* First, calculate how much space we'll need for * the newly sorted block of data. (We don't just * use buf_len for this because we have extracted * comments and whitespace.) */ i = 0; current = master->data; while (current) { i += current->path_len + 1; /* +1 for a tab */ if (current->file_type) { i += current->type_len + 1; /* +1 for a tab */ } i += current->context_len + 1; /* +1 for a newline */ current = current->next; } i = i + 1; /* +1 for trailing \0 */ /* Allocate the buffer for the sorted list. */ *sorted_buf = calloc(i, sizeof(char)); if (!*sorted_buf) { ERR(sh, "Failure allocating memory."); semanage_fc_bucket_list_destroy(master); return -1; } *sorted_buf_len = i; /* Output the sorted semanage_file_context linked list to the char buffer. */ sorted_buf_pos = *sorted_buf; current = master->data; while (current) { /* Output the path. */ i = current->path_len + 1; /* +1 for tab */ snprintf(sorted_buf_pos, i + 1, "%s\t", current->path); sorted_buf_pos = sorted_buf_pos + i; /* Output the type, if there is one. */ if (current->file_type) { i = strlen(current->file_type) + 1; /* +1 for tab */ snprintf(sorted_buf_pos, i + 1, "%s\t", current->file_type); sorted_buf_pos = sorted_buf_pos + i; } /* Output the context. */ i = strlen(current->context) + 1; /* +1 for newline */ snprintf(sorted_buf_pos, i + 1, "%s\n", current->context); sorted_buf_pos = sorted_buf_pos + i; current = current->next; } /* Clean up. */ semanage_fc_bucket_list_destroy(master); /* Sanity check. */ sorted_buf_pos++; if ((sorted_buf_pos - *sorted_buf) != (ssize_t) * sorted_buf_len) { ERR(sh, "Failure writing sorted buffer."); free(*sorted_buf); *sorted_buf = NULL; return -1; } return 0; } /********************* functions that sort netfilter contexts *********************/ #define NC_SORT_NAMES { "pre", "base", "module", "local", "post" } #define NC_SORT_NAMES_LEN { 3, 4, 6, 5, 4 } #define NC_SORT_NEL 5 static void semanage_nc_destroy_ruletab(semanage_netfilter_context_node_t * ruletab[NC_SORT_NEL][2]) { semanage_netfilter_context_node_t *curr, *next; int i; for (i = 0; i < NC_SORT_NEL; i++) { for (curr = ruletab[i][0]; curr != NULL; curr = next) { next = curr->next; free(curr->rule); free(curr); } } } /* Entry function for sorting a set of netfilter context lines. * Returns 0 on success, -1 on failure. * Allocates a buffer pointed to by sorted_buf that contains the sorted lines. * sorted_buf_len is set to the size of this buffer. * This buffer is guaranteed to have a final \0 character. * This buffer must be released by the caller. */ int semanage_nc_sort(semanage_handle_t * sh, const char *buf, size_t buf_len, char **sorted_buf, size_t * sorted_buf_len) { /* parsing bits */ const char *priority_names[] = NC_SORT_NAMES; const int priority_names_len[] = NC_SORT_NAMES_LEN; size_t line_len, buf_remainder, i, offset; const char *line_buf, *line_end; /* ruletab bits */ /* keep track of the head (index 0) and tail (index 1) with this array */ semanage_netfilter_context_node_t *ruletab[NC_SORT_NEL][2]; semanage_netfilter_context_node_t *curr, *node; int priority; /* sorted buffer bits */ char *sorted_buf_pos; size_t count; /* initialize ruletab */ memset(ruletab, 0, NC_SORT_NEL * 2 * sizeof(semanage_netfilter_context_node_t *)); /* while lines to be read */ line_buf = buf; buf_remainder = buf_len; while ((line_end = semanage_get_line_end(line_buf, buf_remainder))) { line_len = line_end - line_buf + 1; buf_remainder = buf_remainder - line_len; if (line_len == 0 || line_len == 1) { line_buf = line_end + 1; continue; } /* Skip the whitespace at the front of the line. */ for (i = 0; i < line_len; i++) { if (!isspace(line_buf[i])) break; } /* Check for a blank line. */ if (i >= line_len) { line_buf = line_end + 1; continue; } /* Check if the line is a comment. */ if (line_buf[i] == '#') { line_buf = line_end + 1; continue; } /* extract priority */ priority = -1; offset = 0; for (i = 0; i < NC_SORT_NEL; i++) { if (strncmp (line_buf, priority_names[i], priority_names_len[i]) == 0) { priority = i; offset = priority_names_len[i]; break; } } if (priority < 0) { ERR(sh, "Netfilter context line missing priority."); semanage_nc_destroy_ruletab(ruletab); return -1; } /* skip over whitespace */ for (; offset < line_len && isspace(line_buf[offset]); offset++) ; /* load rule into node */ node = (semanage_netfilter_context_node_t *) malloc(sizeof(semanage_netfilter_context_node_t)); if (!node) { ERR(sh, "Failure allocating memory."); semanage_nc_destroy_ruletab(ruletab); return -1; } node->rule = (char *)strndup(line_buf + offset, line_len - offset); node->rule_len = line_len - offset; node->next = NULL; if (!node->rule) { ERR(sh, "Failure allocating memory."); free(node); semanage_nc_destroy_ruletab(ruletab); return -1; } /* add node to rule table */ if (ruletab[priority][0] && ruletab[priority][1]) { /* add to end of list, update tail pointer */ ruletab[priority][1]->next = node; ruletab[priority][1] = node; } else { /* this list is empty, make head and tail point to the node */ ruletab[priority][0] = ruletab[priority][1] = node; } line_buf = line_end + 1; } /* First, calculate how much space we'll need for * the newly sorted block of data. (We don't just * use buf_len for this because we have extracted * comments and whitespace.) Start at 1 for trailing \0 */ count = 1; for (i = 0; i < NC_SORT_NEL; i++) for (curr = ruletab[i][0]; curr != NULL; curr = curr->next) count += curr->rule_len; /* Allocate the buffer for the sorted list. */ *sorted_buf = calloc(count, sizeof(char)); if (!*sorted_buf) { ERR(sh, "Failure allocating memory."); semanage_nc_destroy_ruletab(ruletab); return -1; } *sorted_buf_len = count; /* write out rule buffer */ sorted_buf_pos = *sorted_buf; for (i = 0; i < NC_SORT_NEL; i++) { for (curr = ruletab[i][0]; curr != NULL; curr = curr->next) { /* put rule into buffer */ snprintf(sorted_buf_pos, curr->rule_len + 1, "%s\n", curr->rule); /* +1 for newline */ sorted_buf_pos = sorted_buf_pos + curr->rule_len; } } /* free ruletab */ semanage_nc_destroy_ruletab(ruletab); return 0; } libsemanage-2.3/src/semanage_store.h000066400000000000000000000100421233221606300175540ustar00rootroot00000000000000/* Authors: Karl MacMillan * Joshua Brindle * Jason Tang * Christopher Ashworth * * Copyright (C) 2004-2006 Tresys Technology, LLC * Copyright (C) 2005 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SEMANAGE_MODULE_STORE_H #define SEMANAGE_MODULE_STORE_H #include #include #include "handle.h" enum semanage_store_defs { SEMANAGE_ACTIVE, SEMANAGE_PREVIOUS, SEMANAGE_TMP, SEMANAGE_NUM_STORES }; /* sandbox filenames and paths */ enum semanage_sandbox_defs { SEMANAGE_TOPLEVEL, SEMANAGE_MODULES, SEMANAGE_KERNEL, SEMANAGE_BASE, SEMANAGE_LINKED, SEMANAGE_FC, SEMANAGE_HOMEDIR_TMPL, SEMANAGE_FC_TMPL, SEMANAGE_COMMIT_NUM_FILE, SEMANAGE_PORTS_LOCAL, SEMANAGE_INTERFACES_LOCAL, SEMANAGE_NODES_LOCAL, SEMANAGE_BOOLEANS_LOCAL, SEMANAGE_FC_LOCAL, SEMANAGE_SEUSERS_LOCAL, SEMANAGE_USERS_BASE_LOCAL, SEMANAGE_USERS_EXTRA_LOCAL, SEMANAGE_SEUSERS, SEMANAGE_USERS_EXTRA, SEMANAGE_NC, SEMANAGE_FC_HOMEDIRS, SEMANAGE_DISABLE_DONTAUDIT, SEMANAGE_PRESERVE_TUNABLES, SEMANAGE_STORE_NUM_PATHS }; /* FIXME: this needs to be made a module store specific init and the * global configuration moved to another file. */ int semanage_check_init(const char *root); extern const char *semanage_fname(enum semanage_sandbox_defs file_enum); extern const char *semanage_path(enum semanage_store_defs store, enum semanage_sandbox_defs file); int semanage_create_store(semanage_handle_t * sh, int create); int semanage_store_access_check(void); int semanage_remove_directory(const char *path); int semanage_make_sandbox(semanage_handle_t * sh); int semanage_get_modules_names(semanage_handle_t * sh, char ***filenames, int *len); int semanage_module_enabled(const char *file); int semanage_enable_module(const char *file); int semanage_disable_module(const char *file); /* lock file routines */ int semanage_get_trans_lock(semanage_handle_t * sh); int semanage_get_active_lock(semanage_handle_t * sh); void semanage_release_trans_lock(semanage_handle_t * sh); void semanage_release_active_lock(semanage_handle_t * sh); int semanage_direct_get_serial(semanage_handle_t * sh); int semanage_link_sandbox(semanage_handle_t * sh, sepol_module_package_t ** base); int semanage_link_base(semanage_handle_t * sh, sepol_module_package_t ** base); int semanage_expand_sandbox(semanage_handle_t * sh, sepol_module_package_t * base, sepol_policydb_t ** policydb); int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * policydb); int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * policydb); int semanage_install_sandbox(semanage_handle_t * sh); int semanage_verify_modules(semanage_handle_t * sh, char **module_filenames, int num_modules); int semanage_verify_linked(semanage_handle_t * sh); int semanage_verify_kernel(semanage_handle_t * sh); int semanage_split_fc(semanage_handle_t * sh); /* sort file context routines */ int semanage_fc_sort(semanage_handle_t * sh, const char *buf, size_t buf_len, char **sorted_buf, size_t * sorted_buf_len); /* sort netfilter context routines */ int semanage_nc_sort(semanage_handle_t * sh, const char *buf, size_t buf_len, char **sorted_buf, size_t * sorted_buf_len); #endif libsemanage-2.3/src/semanageswig.i000066400000000000000000000042131233221606300172360ustar00rootroot00000000000000/* Author: Spencer Shimko * * Copyright (C) 2004-2005 Tresys Technology, LLC * Copyright (C) 2006 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ %module semanage /* pull in the headers */ %include "../include/semanage/debug.h" %include "../include/semanage/handle.h" %include "../include/semanage/modules.h" %include "../include/semanage/context_record.h" %include "../include/semanage/boolean_record.h" %include "../include/semanage/booleans_policy.h" %include "../include/semanage/booleans_local.h" %include "../include/semanage/booleans_active.h" %include "../include/semanage/iface_record.h" %include "../include/semanage/interfaces_local.h" %include "../include/semanage/interfaces_policy.h" %include "../include/semanage/user_record.h" %include "../include/semanage/users_local.h" %include "../include/semanage/users_policy.h" %include "../include/semanage/port_record.h" %include "../include/semanage/ports_local.h" %include "../include/semanage/ports_policy.h" %include "../include/semanage/fcontext_record.h" %include "../include/semanage/fcontexts_local.h" %include "../include/semanage/fcontexts_policy.h" %include "../include/semanage/seuser_record.h" %include "../include/semanage/seusers_local.h" %include "../include/semanage/seusers_policy.h" %include "../include/semanage/node_record.h" %include "../include/semanage/nodes_local.h" %include "../include/semanage/nodes_policy.h" %include "../include/semanage/semanage.h" libsemanage-2.3/src/semanageswig_python.i000066400000000000000000000306531233221606300206460ustar00rootroot00000000000000/* Author: Spencer Shimko * * Copyright (C) 2004-2005 Tresys Technology, LLC * Copyright (C) 2006 Red Hat, Inc * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** standard typemaps **/ %header %{ #include #include #define STATUS_SUCCESS 0 #define STATUS_ERR -1 %} %wrapper %{ /* There are two ways to call this function: * One is with a valid swig_type and destructor. * Two is with a NULL swig_type and NULL destructor. * * In the first mode, the function converts * an array of *cloned* objects [of the given pointer swig type] * into a PyList, and destroys the array in the process * (the objects pointers are preserved). * * In the second mode, the function converts * an array of *constant* strings into a PyList, and destroys * the array in the process * (the strings are copied, originals not freed). */ static int semanage_array2plist( semanage_handle_t* handle, void** arr, unsigned int asize, swig_type_info* swig_type, void (*destructor) (void*), PyObject** result) { PyObject* plist = PyList_New(0); unsigned int i; if (!plist) goto err; for (i = 0; i < asize; i++) { PyObject* obj = NULL; /* NULL indicates string conversion, * otherwise create an opaque pointer */ if (!swig_type) obj = SWIG_FromCharPtr(arr[i]); else obj = SWIG_NewPointerObj(arr[i], swig_type, 0); if (!obj) goto err; if (PyList_Append(plist, obj) < 0) goto err; } free(arr); *result = plist; return STATUS_SUCCESS; err: for (i = 0; i < asize; i++) if (destructor) destructor(arr[i]); free(arr); return STATUS_ERR; } %} /* a few helpful typemaps are available in this library */ %include /* wrap all int*'s so they can be used for results if it becomes necessary to send in data this should be changed to INOUT */ %apply int *OUTPUT { int * }; %apply int *OUTPUT { size_t * }; %apply int *OUTPUT { unsigned int * }; %typemap(in, numinputs=0) char **(char *temp=NULL) { $1 = &temp; } %typemap(argout) char** { $result = SWIG_Python_AppendOutput($result, SWIG_FromCharPtr(*$1)); free(*$1); } %typemap(in, numinputs=0) char ***(char **temp=NULL) { $1 = &temp; } %typemap(argout) ( semanage_handle_t* handle, const semanage_user_t* user, const char*** roles_arr, unsigned int* num_roles) { if ($result) { int value; SWIG_AsVal_int($result, &value); if (value >= 0) { PyObject* plist = NULL; if (semanage_array2plist($1, (void**) *$3, *$4, NULL, NULL, &plist) < 0) $result = SWIG_From_int(STATUS_ERR); else $result = SWIG_Python_AppendOutput($result, plist); } } } /** module typemaps**/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_module_info_t ** parameter */ %typemap(in, numinputs=0) semanage_module_info_t **(semanage_module_info_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_module_info_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } /** context typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_context_t ** parameter */ %typemap(in, numinputs=0) semanage_context_t **(semanage_context_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_context_t** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } /** boolean typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_bool_t *** parameter */ %typemap(in, numinputs=0) semanage_bool_t ***(semanage_bool_t **temp=NULL) { $1 = &temp; } %typemap(argout) ( semanage_handle_t* handle, semanage_bool_t*** records, unsigned int* count) { if ($result) { int value; SWIG_AsVal_int($result, &value); if (value >= 0) { PyObject* plist = NULL; if (semanage_array2plist($1, (void**) *$2, *$3, SWIGTYPE_p_semanage_bool, (void (*) (void*)) &semanage_bool_free, &plist) < 0) $result = SWIG_From_int(STATUS_ERR); else $result = SWIG_Python_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_bool_t **(semanage_bool_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_bool_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_bool_key_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_bool_key_t **(semanage_bool_key_t *temp=NULL) { $1 = &temp; } /** fcontext typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_fcontext_t *** parameter */ %typemap(in, numinputs=0) semanage_fcontext_t ***(semanage_fcontext_t **temp=NULL) { $1 = &temp; } %typemap(argout) ( semanage_handle_t* handle, semanage_fcontext_t*** records, unsigned int* count) { if ($result) { int value; SWIG_AsVal_int($result, &value); if (value >= 0) { PyObject* plist = NULL; if (semanage_array2plist($1, (void**) *$2, *$3, SWIGTYPE_p_semanage_fcontext, (void (*) (void*)) &semanage_fcontext_free, &plist) < 0) $result = SWIG_From_int(STATUS_ERR); else $result = SWIG_Python_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_fcontext_t **(semanage_fcontext_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_fcontext_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_fcontext_key_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_fcontext_key_t **(semanage_fcontext_key_t *temp=NULL) { $1 = &temp; } /** interface typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_iface_t *** parameter */ %typemap(in, numinputs=0) semanage_iface_t ***(semanage_iface_t **temp=NULL) { $1 = &temp; } %typemap(argout) ( semanage_handle_t* handle, semanage_iface_t*** records, unsigned int* count) { if ($result) { int value; SWIG_AsVal_int($result, &value); if (value >= 0) { PyObject* plist = NULL; if (semanage_array2plist($1, (void**) *$2, *$3, SWIGTYPE_p_semanage_iface, (void (*) (void*)) &semanage_iface_free, &plist) < 0) $result = SWIG_From_int(STATUS_ERR); else $result = SWIG_Python_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_iface_t **(semanage_iface_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_iface_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_iface_key_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_iface_key_t **(semanage_iface_key_t *temp=NULL) { $1 = &temp; } /** seuser typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_seuser_t *** parameter */ %typemap(in, numinputs=0) semanage_seuser_t ***(semanage_seuser_t **temp=NULL) { $1 = &temp; } %typemap(argout) ( semanage_handle_t* handle, semanage_seuser_t*** records, unsigned int* count) { if ($result) { int value; SWIG_AsVal_int($result, &value); if (value >= 0) { PyObject* plist = NULL; if (semanage_array2plist($1, (void**) *$2, *$3, SWIGTYPE_p_semanage_seuser, (void (*) (void*)) &semanage_seuser_free, &plist) < 0) $result = SWIG_From_int(STATUS_ERR); else $result = SWIG_Python_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_seuser_t **(semanage_seuser_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_seuser_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_seuser_key_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_seuser_key_t **(semanage_seuser_key_t *temp=NULL) { $1 = &temp; } /** user typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_user_t *** parameter */ %typemap(in, numinputs=0) semanage_user_t ***(semanage_user_t **temp=NULL) { $1 = &temp; } %typemap(argout) ( semanage_handle_t* handle, semanage_user_t*** records, unsigned int* count) { if ($result) { int value; SWIG_AsVal_int($result, &value); if (value >= 0) { PyObject* plist = NULL; if (semanage_array2plist($1, (void**) *$2, *$3, SWIGTYPE_p_semanage_user, (void (*) (void*)) &semanage_user_free, &plist) < 0) $result = SWIG_From_int(STATUS_ERR); else $result = SWIG_Python_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_user_t **(semanage_user_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_user_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_user_key_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_user_key_t **(semanage_user_key_t *temp=NULL) { $1 = &temp; } /** port typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_port_t *** parameter */ %typemap(in, numinputs=0) semanage_port_t ***(semanage_port_t **temp=NULL) { $1 = &temp; } %typemap(argout) ( semanage_handle_t* handle, semanage_port_t*** records, unsigned int* count) { if ($result) { int value; SWIG_AsVal_int($result, &value); if (value >= 0) { PyObject* plist = NULL; if (semanage_array2plist($1, (void**) *$2, *$3, SWIGTYPE_p_semanage_port, (void (*) (void*)) &semanage_port_free, &plist) < 0) $result = SWIG_From_int(STATUS_ERR); else $result = SWIG_Python_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_port_t **(semanage_port_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_port_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_port_key_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_port_key_t **(semanage_port_key_t *temp=NULL) { $1 = &temp; } /** node typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_node_t *** parameter */ %typemap(in, numinputs=0) semanage_node_t ***(semanage_node_t **temp=NULL) { $1 = &temp; } %typemap(argout) ( semanage_handle_t* handle, semanage_node_t*** records, unsigned int* count) { if ($result) { int value; SWIG_AsVal_int($result, &value); if (value >= 0) { PyObject* plist = NULL; if (semanage_array2plist($1, (void**) *$2, *$3, SWIGTYPE_p_semanage_node, (void (*) (void*)) &semanage_node_free, &plist) < 0) $result = SWIG_From_int(STATUS_ERR); else $result = SWIG_Python_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_node_t **(semanage_node_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_node_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_node_key_t ** { $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_node_key_t **(semanage_node_key_t *temp=NULL) { $1 = &temp; } %include "semanageswig_python_exception.i" %include "semanageswig.i" libsemanage-2.3/src/semanageswig_ruby.i000066400000000000000000000154001233221606300202770ustar00rootroot00000000000000/* Author Dave Quigley * based on semanageswig_python.i by Spencer Shimko */ %header %{ #include #include #define STATUS_SUCCESS 0 #define STATUS_ERR -1 %} /* a few helpful typemaps are available in this library */ %include /* wrap all int*'s so they can be used for results if it becomes necessary to send in data this should be changed to INOUT */ %apply int *OUTPUT { int * }; %apply int *OUTPUT { size_t * }; %apply int *OUTPUT { unsigned int * }; %typemap(in, numinputs=0) char **(char *temp=NULL) { $1 = &temp; } %typemap(argout) char** { %append_output(SWIG_FromCharPtr(*$1)); free(*$1); } %typemap(in, numinputs=0) char ***(char **temp=NULL) { $1 = &temp; } /* the wrapper will setup this parameter for passing... the resulting ruby functions will not take the semanage_module_info_t ** parameter */ %typemap(in, numinputs=0) semanage_module_info_t **(semanage_module_info_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_module_info_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } /** context typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_context_t ** parameter */ %typemap(in, numinputs=0) semanage_context_t **(semanage_context_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_context_t** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } /** boolean typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_bool_t *** parameter */ %typemap(in, numinputs=0) semanage_bool_t ***(semanage_bool_t **temp=NULL) { $1 = &temp; } %typemap(in, numinputs=0) semanage_bool_t **(semanage_bool_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_bool_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_bool_key_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_bool_key_t **(semanage_bool_key_t *temp=NULL) { $1 = &temp; } /** fcontext typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_fcontext_t *** parameter */ %typemap(in, numinputs=0) semanage_fcontext_t ***(semanage_fcontext_t **temp=NULL) { $1 = &temp; } %typemap(in, numinputs=0) semanage_fcontext_t **(semanage_fcontext_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_fcontext_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_fcontext_key_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_fcontext_key_t **(semanage_fcontext_key_t *temp=NULL) { $1 = &temp; } /** interface typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_iface_t *** parameter */ %typemap(in, numinputs=0) semanage_iface_t ***(semanage_iface_t **temp=NULL) { $1 = &temp; } %typemap(in, numinputs=0) semanage_iface_t **(semanage_iface_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_iface_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_iface_key_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_iface_key_t **(semanage_iface_key_t *temp=NULL) { $1 = &temp; } /** seuser typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_seuser_t *** parameter */ %typemap(in, numinputs=0) semanage_seuser_t ***(semanage_seuser_t **temp=NULL) { $1 = &temp; } %typemap(in, numinputs=0) semanage_seuser_t **(semanage_seuser_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_seuser_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_seuser_key_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_seuser_key_t **(semanage_seuser_key_t *temp=NULL) { $1 = &temp; } /** user typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_user_t *** parameter */ %typemap(in, numinputs=0) semanage_user_t ***(semanage_user_t **temp=NULL) { $1 = &temp; } %typemap(in, numinputs=0) semanage_user_t **(semanage_user_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_user_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_user_key_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_user_key_t **(semanage_user_key_t *temp=NULL) { $1 = &temp; } /** port typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_port_t *** parameter */ %typemap(in, numinputs=0) semanage_port_t ***(semanage_port_t **temp=NULL) { $1 = &temp; } %typemap(in, numinputs=0) semanage_port_t **(semanage_port_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_port_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_port_key_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_port_key_t **(semanage_port_key_t *temp=NULL) { $1 = &temp; } /** node typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_node_t *** parameter */ %typemap(in, numinputs=0) semanage_node_t ***(semanage_node_t **temp=NULL) { $1 = &temp; } %typemap(in, numinputs=0) semanage_node_t **(semanage_node_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_node_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_node_key_t ** { $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_node_key_t **(semanage_node_key_t *temp=NULL) { $1 = &temp; } %include "semanageswig.i" libsemanage-2.3/src/seuser_internal.h000066400000000000000000000025251233221606300177710ustar00rootroot00000000000000#ifndef _SEMANAGE_SEUSER_INTERNAL_H_ #define _SEMANAGE_SEUSER_INTERNAL_H_ #include #include #include #include #include "database.h" #include "handle.h" #include "dso.h" hidden_proto(semanage_seuser_clone) hidden_proto(semanage_seuser_compare) hidden_proto(semanage_seuser_compare2) hidden_proto(semanage_seuser_create) hidden_proto(semanage_seuser_free) hidden_proto(semanage_seuser_get_mlsrange) hidden_proto(semanage_seuser_get_name) hidden_proto(semanage_seuser_get_sename) hidden_proto(semanage_seuser_key_create) hidden_proto(semanage_seuser_key_extract) hidden_proto(semanage_seuser_key_free) hidden_proto(semanage_seuser_set_mlsrange) hidden_proto(semanage_seuser_set_name) hidden_proto(semanage_seuser_set_sename) hidden_proto(semanage_seuser_iterate) hidden_proto(semanage_seuser_iterate_local) /* SEUSER RECORD: method table */ extern record_table_t SEMANAGE_SEUSER_RTABLE; extern int seuser_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig); extern void seuser_file_dbase_release(dbase_config_t * dconfig); extern int hidden semanage_seuser_validate_local(semanage_handle_t * handle, const sepol_policydb_t * policydb); #endif libsemanage-2.3/src/seuser_record.c000066400000000000000000000132401233221606300174220ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: semanage_seuser_t (Unix User) * Object: semanage_seuser_key_t (Unix User Key) * Implements: record_t (Database Record) * Implements: record_key_t (Database Record Key) */ struct semanage_seuser; struct semanage_seuser_key; typedef struct semanage_seuser record_t; typedef struct semanage_seuser_key record_key_t; #define DBASE_RECORD_DEFINED #include #include #include "seuser_internal.h" #include "debug.h" #include #include "database.h" struct semanage_seuser { /* This user's name */ char *name; /* This user's corresponding * seuser ("role set") */ char *sename; /* This user's mls range (only required for mls) */ char *mls_range; }; struct semanage_seuser_key { /* This user's name */ const char *name; }; int semanage_seuser_key_create(semanage_handle_t * handle, const char *name, semanage_seuser_key_t ** key_ptr) { semanage_seuser_key_t *tmp_key = (semanage_seuser_key_t *) malloc(sizeof(semanage_seuser_key_t)); if (!tmp_key) { ERR(handle, "out of memory, could not create seuser key"); return STATUS_ERR; } tmp_key->name = name; *key_ptr = tmp_key; return STATUS_SUCCESS; } hidden_def(semanage_seuser_key_create) int semanage_seuser_key_extract(semanage_handle_t * handle, const semanage_seuser_t * seuser, semanage_seuser_key_t ** key_ptr) { if (semanage_seuser_key_create(handle, seuser->name, key_ptr) < 0) goto err; return STATUS_SUCCESS; err: ERR(handle, "could not extract seuser key from record"); return STATUS_ERR; } hidden_def(semanage_seuser_key_extract) void semanage_seuser_key_free(semanage_seuser_key_t * key) { free(key); } hidden_def(semanage_seuser_key_free) int semanage_seuser_compare(const semanage_seuser_t * seuser, const semanage_seuser_key_t * key) { return strcmp(seuser->name, key->name); } hidden_def(semanage_seuser_compare) int semanage_seuser_compare2(const semanage_seuser_t * seuser, const semanage_seuser_t * seuser2) { return strcmp(seuser->name, seuser2->name); } hidden_def(semanage_seuser_compare2) static int semanage_seuser_compare2_qsort(const semanage_seuser_t ** seuser, const semanage_seuser_t ** seuser2) { return strcmp((*seuser)->name, (*seuser2)->name); } /* Name */ const char *semanage_seuser_get_name(const semanage_seuser_t * seuser) { return seuser->name; } hidden_def(semanage_seuser_get_name) int semanage_seuser_set_name(semanage_handle_t * handle, semanage_seuser_t * seuser, const char *name) { char *tmp_name = strdup(name); if (!tmp_name) { ERR(handle, "out of memory, could not set seuser (Unix) name"); return STATUS_ERR; } free(seuser->name); seuser->name = tmp_name; return STATUS_SUCCESS; } hidden_def(semanage_seuser_set_name) /* Selinux Name */ const char *semanage_seuser_get_sename(const semanage_seuser_t * seuser) { return seuser->sename; } hidden_def(semanage_seuser_get_sename) int semanage_seuser_set_sename(semanage_handle_t * handle, semanage_seuser_t * seuser, const char *sename) { char *tmp_sename = strdup(sename); if (!tmp_sename) { ERR(handle, "out of memory, could not set seuser (SELinux) name"); return STATUS_ERR; } free(seuser->sename); seuser->sename = tmp_sename; return STATUS_SUCCESS; } hidden_def(semanage_seuser_set_sename) /* MLS Range */ const char *semanage_seuser_get_mlsrange(const semanage_seuser_t * seuser) { return seuser->mls_range; } hidden_def(semanage_seuser_get_mlsrange) int semanage_seuser_set_mlsrange(semanage_handle_t * handle, semanage_seuser_t * seuser, const char *mls_range) { char *tmp_mls_range = strdup(mls_range); if (!tmp_mls_range) { ERR(handle, "out of memory, could not set seuser MLS range"); return STATUS_ERR; } free(seuser->mls_range); seuser->mls_range = tmp_mls_range; return STATUS_SUCCESS; } hidden_def(semanage_seuser_set_mlsrange) /* Create */ int semanage_seuser_create(semanage_handle_t * handle, semanage_seuser_t ** seuser_ptr) { semanage_seuser_t *seuser = (semanage_seuser_t *) malloc(sizeof(semanage_seuser_t)); if (!seuser) { ERR(handle, "out of memory, could not create seuser"); return STATUS_ERR; } seuser->name = NULL; seuser->sename = NULL; seuser->mls_range = NULL; *seuser_ptr = seuser; return STATUS_SUCCESS; } hidden_def(semanage_seuser_create) /* Deep copy clone */ int semanage_seuser_clone(semanage_handle_t * handle, const semanage_seuser_t * seuser, semanage_seuser_t ** seuser_ptr) { semanage_seuser_t *new_seuser = NULL; if (semanage_seuser_create(handle, &new_seuser) < 0) goto err; if (semanage_seuser_set_name(handle, new_seuser, seuser->name) < 0) goto err; if (semanage_seuser_set_sename(handle, new_seuser, seuser->sename) < 0) goto err; if (seuser->mls_range && (semanage_seuser_set_mlsrange(handle, new_seuser, seuser->mls_range) < 0)) goto err; *seuser_ptr = new_seuser; return STATUS_SUCCESS; err: ERR(handle, "could not clone seuser"); semanage_seuser_free(new_seuser); return STATUS_ERR; } hidden_def(semanage_seuser_clone) /* Destroy */ void semanage_seuser_free(semanage_seuser_t * seuser) { if (!seuser) return; free(seuser->name); free(seuser->sename); free(seuser->mls_range); free(seuser); } hidden_def(semanage_seuser_free) /* Record base functions */ record_table_t SEMANAGE_SEUSER_RTABLE = { .create = semanage_seuser_create, .key_extract = semanage_seuser_key_extract, .key_free = semanage_seuser_key_free, .clone = semanage_seuser_clone, .compare = semanage_seuser_compare, .compare2 = semanage_seuser_compare2, .compare2_qsort = semanage_seuser_compare2_qsort, .free = semanage_seuser_free, }; libsemanage-2.3/src/seusers_file.c000066400000000000000000000056211233221606300172520ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_seuser; struct semanage_seuser_key; typedef struct semanage_seuser record_t; typedef struct semanage_seuser_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_file; typedef struct dbase_file dbase_t; #define DBASE_DEFINED #include #include #include "seuser_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" #include "handle.h" static int seuser_print(semanage_handle_t * handle, semanage_seuser_t * seuser, FILE * str) { const char *name = semanage_seuser_get_name(seuser); const char *sename = semanage_seuser_get_sename(seuser); const char *mls = semanage_seuser_get_mlsrange(seuser); if (fprintf(str, "%s:%s", name, sename) < 0) goto err; if (mls != NULL && fprintf(str, ":%s", mls) < 0) goto err; fprintf(str, "\n"); return STATUS_SUCCESS; err: ERR(handle, "could not print seuser %s to stream", name); return STATUS_ERR; } static int seuser_parse(semanage_handle_t * handle, parse_info_t * info, semanage_seuser_t * seuser) { char *str = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (!info->ptr) goto last; /* Extract name */ if (parse_fetch_string(handle, info, &str, ':') < 0) goto err; if (semanage_seuser_set_name(handle, seuser, str) < 0) goto err; free(str); str = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (parse_assert_ch(handle, info, ':') < 0) goto err; if (parse_skip_space(handle, info) < 0) goto err; /* Extract sename */ if (parse_fetch_string(handle, info, &str, ':') < 0) goto err; if (semanage_seuser_set_sename(handle, seuser, str) < 0) goto err; free(str); str = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (parse_optional_ch(info, ':') == STATUS_NODATA) goto out; if (parse_skip_space(handle, info) < 0) goto err; /* NOTE: does not allow spaces/multiline */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_seuser_set_mlsrange(handle, seuser, str) < 0) goto err; free(str); str = NULL; if (parse_assert_space(handle, info) < 0) goto err; out: return STATUS_SUCCESS; last: parse_dispose_line(info); return STATUS_NODATA; err: ERR(handle, "could not parse seuser record"); free(str); parse_dispose_line(info); return STATUS_ERR; } /* SEUSER RECORD: FILE extension: method table */ record_file_table_t SEMANAGE_SEUSER_FILE_RTABLE = { .parse = seuser_parse, .print = seuser_print, }; int seuser_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig) { if (dbase_file_init(handle, fname, &SEMANAGE_SEUSER_RTABLE, &SEMANAGE_SEUSER_FILE_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_FILE_DTABLE; return STATUS_SUCCESS; } void seuser_file_dbase_release(dbase_config_t * dconfig) { dbase_file_release(dconfig->dbase); } libsemanage-2.3/src/seusers_local.c000066400000000000000000000211571233221606300174270ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_seuser; struct semanage_seuser_key; typedef struct semanage_seuser_key record_key_t; typedef struct semanage_seuser record_t; #define DBASE_RECORD_DEFINED #include #include #include #include #include "user_internal.h" #include "seuser_internal.h" #include "handle.h" #include "database.h" #include "debug.h" #include "string.h" #include static char *semanage_user_roles(semanage_handle_t * handle, const char *sename) { char *roles = NULL; unsigned int num_roles; size_t i; size_t size = 0; const char **roles_arr; semanage_user_key_t *key = NULL; semanage_user_t * user; if (semanage_user_key_create(handle, sename, &key) >= 0) { if (semanage_user_query(handle, key, &user) >= 0) { if (semanage_user_get_roles(handle, user, &roles_arr, &num_roles) >= 0) { for (i = 0; imsg_callback; dbase_config_t *dconfig = semanage_seuser_dbase_local(handle); const char *sename = semanage_seuser_get_sename(data); const char *mls_range = semanage_seuser_get_mlsrange(data); semanage_seuser_t *previous = NULL; semanage_seuser_t *new = NULL; if (!sename) { errno=EINVAL; return -1; } if (semanage_seuser_clone(handle, data, &new) < 0) { goto err; } if (!mls_range && semanage_mls_enabled(handle)) { semanage_user_key_t *ukey = NULL; semanage_user_t *u = NULL; rc = semanage_user_key_create(handle, sename, &ukey); if (rc < 0) goto err; rc = semanage_user_query(handle, ukey, &u); semanage_user_key_free(ukey); if (rc >= 0 ) { mls_range = semanage_user_get_mlsrange(u); rc = semanage_seuser_set_mlsrange(handle, new, mls_range); semanage_user_free(u); } if (rc < 0) goto err; } handle->msg_callback = NULL; (void) semanage_seuser_query(handle, key, &previous); handle->msg_callback = callback; rc = dbase_modify(handle, dconfig, key, new); if (semanage_seuser_audit(handle, new, previous, AUDIT_ROLE_ASSIGN, rc == 0) < 0) rc = -1; err: if (previous) semanage_seuser_free(previous); semanage_seuser_free(new); return rc; } int semanage_seuser_del_local(semanage_handle_t * handle, const semanage_seuser_key_t * key) { int rc; semanage_seuser_t *seuser = NULL; dbase_config_t *dconfig = semanage_seuser_dbase_local(handle); rc = dbase_del(handle, dconfig, key); semanage_seuser_query(handle, key, &seuser); if (semanage_seuser_audit(handle, NULL, seuser, AUDIT_ROLE_REMOVE, rc == 0) < 0) rc = -1; if (seuser) semanage_seuser_free(seuser); return rc; } int semanage_seuser_query_local(semanage_handle_t * handle, const semanage_seuser_key_t * key, semanage_seuser_t ** response) { dbase_config_t *dconfig = semanage_seuser_dbase_local(handle); return dbase_query(handle, dconfig, key, response); } int semanage_seuser_exists_local(semanage_handle_t * handle, const semanage_seuser_key_t * key, int *response) { dbase_config_t *dconfig = semanage_seuser_dbase_local(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_seuser_count_local(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_seuser_dbase_local(handle); return dbase_count(handle, dconfig, response); } int semanage_seuser_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_seuser_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_seuser_dbase_local(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } hidden_def(semanage_seuser_iterate_local) int semanage_seuser_list_local(semanage_handle_t * handle, semanage_seuser_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_seuser_dbase_local(handle); return dbase_list(handle, dconfig, records, count); } struct validate_handler_arg { semanage_handle_t *handle; const sepol_policydb_t *policydb; }; static int validate_handler(const semanage_seuser_t * seuser, void *varg) { semanage_user_t *user = NULL; semanage_user_key_t *key = NULL; int exists, mls_ok; /* Unpack varg */ struct validate_handler_arg *arg = (struct validate_handler_arg *)varg; semanage_handle_t *handle = arg->handle; const sepol_policydb_t *policydb = arg->policydb; /* Unpack seuser */ const char *name = semanage_seuser_get_name(seuser); const char *sename = semanage_seuser_get_sename(seuser); const char *mls_range = semanage_seuser_get_mlsrange(seuser); const char *user_mls_range; /* Make sure the (SElinux) user exists */ if (semanage_user_key_create(handle, sename, &key) < 0) goto err; if (semanage_user_exists(handle, key, &exists) < 0) goto err; if (!exists) { ERR(handle, "selinux user %s does not exist", sename); goto invalid; } /* Verify that the mls range is valid, and that it's contained * within the (SELinux) user mls range. This range is optional */ if (mls_range && sepol_policydb_mls_enabled(policydb)) { if (semanage_user_query(handle, key, &user) < 0) goto err; user_mls_range = semanage_user_get_mlsrange(user); if (sepol_mls_check(handle->sepolh, policydb, mls_range) < 0) goto invalid; if (sepol_mls_contains(handle->sepolh, policydb, user_mls_range, mls_range, &mls_ok) < 0) goto err; if (!mls_ok) { ERR(handle, "MLS range %s for Unix user %s " "exceeds allowed range %s for SELinux user %s", mls_range, name, user_mls_range, sename); goto invalid; } } else if (mls_range) { ERR(handle, "MLS is disabled, but MLS range %s " "was found for Unix user %s", mls_range, name); goto invalid; } semanage_user_key_free(key); semanage_user_free(user); return 0; err: ERR(handle, "could not check if seuser mapping for %s is valid", name); semanage_user_key_free(key); semanage_user_free(user); return -1; invalid: if (mls_range) ERR(handle, "seuser mapping [%s -> (%s, %s)] is invalid", name, sename, mls_range); else ERR(handle, "seuser mapping [%s -> %s] is invalid", name, sename); semanage_user_key_free(key); semanage_user_free(user); return -1; } /* This function may not be called outside a transaction, or * it will (1) deadlock, because iterate is not reentrant outside * a transaction, and (2) be racy, because it makes multiple dbase calls */ int hidden semanage_seuser_validate_local(semanage_handle_t * handle, const sepol_policydb_t * policydb) { struct validate_handler_arg arg; arg.handle = handle; arg.policydb = policydb; return semanage_seuser_iterate_local(handle, validate_handler, &arg); } libsemanage-2.3/src/seusers_policy.c000066400000000000000000000031341233221606300176270ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_seuser; struct semanage_seuser_key; typedef struct semanage_seuser_key record_key_t; typedef struct semanage_seuser record_t; #define DBASE_RECORD_DEFINED #include #include #include "user_internal.h" #include "seuser_internal.h" #include "handle.h" #include "database.h" #include "debug.h" int semanage_seuser_query(semanage_handle_t * handle, const semanage_seuser_key_t * key, semanage_seuser_t ** response) { dbase_config_t *dconfig = semanage_seuser_dbase_policy(handle); return dbase_query(handle, dconfig, key, response); } int semanage_seuser_exists(semanage_handle_t * handle, const semanage_seuser_key_t * key, int *response) { dbase_config_t *dconfig = semanage_seuser_dbase_policy(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_seuser_count(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_seuser_dbase_policy(handle); return dbase_count(handle, dconfig, response); } int semanage_seuser_iterate(semanage_handle_t * handle, int (*handler) (const semanage_seuser_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_seuser_dbase_policy(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } hidden_def(semanage_seuser_iterate) int semanage_seuser_list(semanage_handle_t * handle, semanage_seuser_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_seuser_dbase_policy(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-2.3/src/user_base_record.c000066400000000000000000000106201233221606300200630ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: semanage_user_base_t (SELinux User/Class Policy Object) * Object: semanage_user_key_t (SELinux User/Class Key) * Implements: record_t (Database Record) * Implements: record_key_t (Database Record Key) */ #include typedef sepol_user_key_t semanage_user_key_t; #define _SEMANAGE_USER_KEY_DEFINED_ typedef sepol_user_t semanage_user_base_t; #define _SEMANAGE_USER_BASE_DEFINED_ typedef semanage_user_base_t record_t; typedef semanage_user_key_t record_key_t; #define DBASE_RECORD_DEFINED #include #include "user_internal.h" #include "handle.h" #include "database.h" #include "debug.h" /* Key */ hidden int semanage_user_base_key_extract(semanage_handle_t * handle, const semanage_user_base_t * user, semanage_user_key_t ** key) { return sepol_user_key_extract(handle->sepolh, user, key); } static int semanage_user_base_compare(const semanage_user_base_t * user, const semanage_user_key_t * key) { return sepol_user_compare(user, key); } static int semanage_user_base_compare2(const semanage_user_base_t * user, const semanage_user_base_t * user2) { return sepol_user_compare2(user, user2); } static int semanage_user_base_compare2_qsort(const semanage_user_base_t ** user, const semanage_user_base_t ** user2) { return sepol_user_compare2(*user, *user2); } /* Name */ hidden const char *semanage_user_base_get_name(const semanage_user_base_t * user) { return sepol_user_get_name(user); } hidden int semanage_user_base_set_name(semanage_handle_t * handle, semanage_user_base_t * user, const char *name) { return sepol_user_set_name(handle->sepolh, user, name); } /* MLS */ hidden const char *semanage_user_base_get_mlslevel(const semanage_user_base_t * user) { return sepol_user_get_mlslevel(user); } hidden int semanage_user_base_set_mlslevel(semanage_handle_t * handle, semanage_user_base_t * user, const char *mls_level) { return sepol_user_set_mlslevel(handle->sepolh, user, mls_level); } hidden const char *semanage_user_base_get_mlsrange(const semanage_user_base_t * user) { return sepol_user_get_mlsrange(user); } hidden int semanage_user_base_set_mlsrange(semanage_handle_t * handle, semanage_user_base_t * user, const char *mls_range) { return sepol_user_set_mlsrange(handle->sepolh, user, mls_range); } /* Role management */ hidden int semanage_user_base_get_num_roles(const semanage_user_base_t * user) { return sepol_user_get_num_roles(user); } hidden int semanage_user_base_add_role(semanage_handle_t * handle, semanage_user_base_t * user, const char *role) { return sepol_user_add_role(handle->sepolh, user, role); } hidden void semanage_user_base_del_role(semanage_user_base_t * user, const char *role) { sepol_user_del_role(user, role); } hidden int semanage_user_base_has_role(const semanage_user_base_t * user, const char *role) { return sepol_user_has_role(user, role); } hidden int semanage_user_base_get_roles(semanage_handle_t * handle, const semanage_user_base_t * user, const char ***roles_arr, unsigned int *num_roles) { return sepol_user_get_roles(handle->sepolh, user, roles_arr, num_roles); } hidden int semanage_user_base_set_roles(semanage_handle_t * handle, semanage_user_base_t * user, const char **roles_arr, unsigned int num_roles) { return sepol_user_set_roles(handle->sepolh, user, roles_arr, num_roles); } /* Create/Clone/Destroy */ hidden int semanage_user_base_create(semanage_handle_t * handle, semanage_user_base_t ** user_ptr) { return sepol_user_create(handle->sepolh, user_ptr); } hidden int semanage_user_base_clone(semanage_handle_t * handle, const semanage_user_base_t * user, semanage_user_base_t ** user_ptr) { return sepol_user_clone(handle->sepolh, user, user_ptr); } hidden void semanage_user_base_free(semanage_user_base_t * user) { sepol_user_free(user); } /* Record base functions */ record_table_t SEMANAGE_USER_BASE_RTABLE = { .create = semanage_user_base_create, .key_extract = semanage_user_base_key_extract, .key_free = semanage_user_key_free, .clone = semanage_user_base_clone, .compare = semanage_user_base_compare, .compare2 = semanage_user_base_compare2, .compare2_qsort = semanage_user_base_compare2_qsort, .free = semanage_user_base_free, }; libsemanage-2.3/src/user_extra_record.c000066400000000000000000000111521233221606300202750ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: semanage_user_extra_t (SELinux User/Class Extra Data) * Object: semanage_user_extra_key_t (SELinux User/Class Key) * Implements: record_t (Database Record) * Implements: record_key_t (Database Record Key) */ #include typedef sepol_user_key_t semanage_user_key_t; #define _SEMANAGE_USER_KEY_DEFINED_ struct semanage_user_extra; typedef struct semanage_user_extra record_t; typedef semanage_user_key_t record_key_t; #define DBASE_RECORD_DEFINED #include #include #include #include "user_internal.h" #include "debug.h" #include "database.h" struct semanage_user_extra { /* This user's name */ char *name; /* Labeling prefix */ char *prefix; }; static int semanage_user_extra_key_extract(semanage_handle_t * handle, const semanage_user_extra_t * user_extra, semanage_user_key_t ** key_ptr) { if (semanage_user_key_create(handle, user_extra->name, key_ptr) < 0) goto err; return STATUS_SUCCESS; err: ERR(handle, "could not extract key from user extra record"); return STATUS_ERR; } static int semanage_user_extra_compare(const semanage_user_extra_t * user_extra, const semanage_user_key_t * key) { const char *name; semanage_user_key_unpack(key, &name); return strcmp(user_extra->name, name); } static int semanage_user_extra_compare2(const semanage_user_extra_t * user_extra, const semanage_user_extra_t * user_extra2) { return strcmp(user_extra->name, user_extra2->name); } static int semanage_user_extra_compare2_qsort(const semanage_user_extra_t ** user_extra, const semanage_user_extra_t ** user_extra2) { return strcmp((*user_extra)->name, (*user_extra2)->name); } /* Name */ hidden const char *semanage_user_extra_get_name(const semanage_user_extra_t * user_extra) { return user_extra->name; } hidden int semanage_user_extra_set_name(semanage_handle_t * handle, semanage_user_extra_t * user_extra, const char *name) { char *tmp_name = strdup(name); if (!tmp_name) { ERR(handle, "out of memory, could not set name %s " "for user extra data", name); return STATUS_ERR; } free(user_extra->name); user_extra->name = tmp_name; return STATUS_SUCCESS; } /* Labeling prefix */ hidden const char *semanage_user_extra_get_prefix(const semanage_user_extra_t * user_extra) { return user_extra->prefix; } hidden int semanage_user_extra_set_prefix(semanage_handle_t * handle, semanage_user_extra_t * user_extra, const char *prefix) { char *tmp_prefix = strdup(prefix); if (!tmp_prefix) { ERR(handle, "out of memory, could not set prefix %s " "for user %s", prefix, user_extra->name); return STATUS_ERR; } free(user_extra->prefix); user_extra->prefix = tmp_prefix; return STATUS_SUCCESS; } /* Create */ hidden int semanage_user_extra_create(semanage_handle_t * handle, semanage_user_extra_t ** user_extra_ptr) { semanage_user_extra_t *user_extra = (semanage_user_extra_t *) malloc(sizeof(semanage_user_extra_t)); if (!user_extra) { ERR(handle, "out of memory, could not " "create user extra data record"); return STATUS_ERR; } user_extra->name = NULL; user_extra->prefix = NULL; *user_extra_ptr = user_extra; return STATUS_SUCCESS; } /* Destroy */ hidden void semanage_user_extra_free(semanage_user_extra_t * user_extra) { if (!user_extra) return; free(user_extra->name); free(user_extra->prefix); free(user_extra); } /* Deep copy clone */ hidden int semanage_user_extra_clone(semanage_handle_t * handle, const semanage_user_extra_t * user_extra, semanage_user_extra_t ** user_extra_ptr) { semanage_user_extra_t *new_user_extra = NULL; if (semanage_user_extra_create(handle, &new_user_extra) < 0) goto err; if (semanage_user_extra_set_name (handle, new_user_extra, user_extra->name) < 0) goto err; if (semanage_user_extra_set_prefix (handle, new_user_extra, user_extra->prefix) < 0) goto err; *user_extra_ptr = new_user_extra; return STATUS_SUCCESS; err: ERR(handle, "could not clone extra data for user %s", user_extra->name); semanage_user_extra_free(new_user_extra); return STATUS_ERR; } /* Record base functions */ record_table_t SEMANAGE_USER_EXTRA_RTABLE = { .create = semanage_user_extra_create, .key_extract = semanage_user_extra_key_extract, .key_free = semanage_user_key_free, .clone = semanage_user_extra_clone, .compare = semanage_user_extra_compare, .compare2 = semanage_user_extra_compare2, .compare2_qsort = semanage_user_extra_compare2_qsort, .free = semanage_user_extra_free, }; libsemanage-2.3/src/user_internal.h000066400000000000000000000134571233221606300174470ustar00rootroot00000000000000#ifndef _SEMANAGE_USER_INTERNAL_H_ #define _SEMANAGE_USER_INTERNAL_H_ #include #include #include #include #include "database.h" #include "handle.h" #include "dso.h" hidden_proto(semanage_user_add_role) hidden_proto(semanage_user_clone) hidden_proto(semanage_user_compare) hidden_proto(semanage_user_compare2) hidden_proto(semanage_user_create) hidden_proto(semanage_user_free) hidden_proto(semanage_user_get_mlslevel) hidden_proto(semanage_user_get_mlsrange) hidden_proto(semanage_user_get_name) hidden_proto(semanage_user_get_roles) hidden_proto(semanage_user_key_create) hidden_proto(semanage_user_key_extract) hidden_proto(semanage_user_key_free) hidden_proto(semanage_user_set_mlslevel) hidden_proto(semanage_user_set_mlsrange) hidden_proto(semanage_user_set_name) hidden_proto(semanage_user_exists) hidden_proto(semanage_user_query) /* USER record: metod table */ extern record_table_t SEMANAGE_USER_RTABLE; /* USER BASE record: method table */ extern record_table_t SEMANAGE_USER_BASE_RTABLE; /* USER EXTRA record: method table */ extern record_table_t SEMANAGE_USER_EXTRA_RTABLE; /* ============ Init/Release functions ========== */ /* USER BASE record, FILE backend */ extern int user_base_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig); extern void user_base_file_dbase_release(dbase_config_t * dconfig); /* USER EXTRA record, FILE backend */ extern int user_extra_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig); extern void user_extra_file_dbase_release(dbase_config_t * dconfig); /* USER BASE record, POLICYDB backend */ extern int user_base_policydb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig); extern void user_base_policydb_dbase_release(dbase_config_t * dconfig); /* USER record, JOIN backend */ extern int user_join_dbase_init(semanage_handle_t * handle, dbase_config_t * join1, dbase_config_t * join2, dbase_config_t * dconfig); extern void user_join_dbase_release(dbase_config_t * dconfig); /*======= Internal API: Base (Policy) User record ====== */ #ifndef _SEMANAGE_USER_BASE_DEFINED_ struct semanage_user_base; typedef struct semanage_user_base semanage_user_base_t; #define _SEMANAGE_USER_BASE_DEFINED_ #endif hidden int semanage_user_base_create(semanage_handle_t * handle, semanage_user_base_t ** user_ptr); hidden int semanage_user_base_clone(semanage_handle_t * handle, const semanage_user_base_t * user, semanage_user_base_t ** user_ptr); hidden int semanage_user_base_key_extract(semanage_handle_t * handle, const semanage_user_base_t * user, semanage_user_key_t ** key); hidden const char *semanage_user_base_get_name(const semanage_user_base_t * user); hidden int semanage_user_base_set_name(semanage_handle_t * handle, semanage_user_base_t * user, const char *name); hidden const char *semanage_user_base_get_mlslevel(const semanage_user_base_t * user); hidden int semanage_user_base_set_mlslevel(semanage_handle_t * handle, semanage_user_base_t * user, const char *mls_level); hidden const char *semanage_user_base_get_mlsrange(const semanage_user_base_t * user); hidden int semanage_user_base_set_mlsrange(semanage_handle_t * handle, semanage_user_base_t * user, const char *mls_range); hidden int semanage_user_base_get_num_roles(const semanage_user_base_t * user); hidden int semanage_user_base_add_role(semanage_handle_t * handle, semanage_user_base_t * user, const char *role); hidden void semanage_user_base_del_role(semanage_user_base_t * user, const char *role); hidden int semanage_user_base_has_role(const semanage_user_base_t * user, const char *role); hidden int semanage_user_base_get_roles(semanage_handle_t * handle, const semanage_user_base_t * user, const char ***roles_arr, unsigned int *num_roles); hidden int semanage_user_base_set_roles(semanage_handle_t * handle, semanage_user_base_t * user, const char **roles_arr, unsigned int num_roles); hidden void semanage_user_base_free(semanage_user_base_t * user); /*=========== Internal API: Extra User record ==========*/ struct semanage_user_extra; typedef struct semanage_user_extra semanage_user_extra_t; hidden int semanage_user_extra_create(semanage_handle_t * handle, semanage_user_extra_t ** user_extra_ptr); hidden int semanage_user_extra_clone(semanage_handle_t * handle, const semanage_user_extra_t * user_extra, semanage_user_extra_t ** user_extra_ptr); hidden const char *semanage_user_extra_get_name(const semanage_user_extra_t * user_extra); hidden int semanage_user_extra_set_name(semanage_handle_t * handle, semanage_user_extra_t * user_extra, const char *name); hidden const char *semanage_user_extra_get_prefix(const semanage_user_extra_t * user_extra); hidden int semanage_user_extra_set_prefix(semanage_handle_t * handle, semanage_user_extra_t * user_extra, const char *prefix); hidden void semanage_user_extra_free(semanage_user_extra_t * user_extra); /*======== Internal API: Join record ========== */ hidden void semanage_user_key_unpack(const semanage_user_key_t * key, const char **name); hidden int semanage_user_join(semanage_handle_t * handle, const semanage_user_base_t * record1, const semanage_user_extra_t * record2, semanage_user_t ** result); hidden int semanage_user_split(semanage_handle_t * handle, const semanage_user_t * record, semanage_user_base_t ** split1, semanage_user_extra_t ** split2); #endif libsemanage-2.3/src/user_record.c000066400000000000000000000224301233221606300170730ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ /* Object: semanage_user_t (SELinux User/Class) * Object: semanage_user_key_t (SELinux User/Class Key) * Implements: record_t (Database Record) * Implements: record_key_t (Database Record Key) */ #include typedef sepol_user_key_t semanage_user_key_t; #define _SEMANAGE_USER_KEY_DEFINED_ struct semanage_user; typedef struct semanage_user record_t; typedef semanage_user_key_t record_key_t; #define DBASE_RECORD_DEFINED #include #include #include "user_internal.h" #include "handle.h" #include "database.h" #include "debug.h" struct semanage_user { char *name; semanage_user_base_t *base; semanage_user_extra_t *extra; }; /* Key */ int semanage_user_key_create(semanage_handle_t * handle, const char *name, semanage_user_key_t ** key) { return sepol_user_key_create(handle->sepolh, name, key); } hidden_def(semanage_user_key_create) int semanage_user_key_extract(semanage_handle_t * handle, const semanage_user_t * user, semanage_user_key_t ** key) { return semanage_user_base_key_extract(handle, user->base, key); } hidden_def(semanage_user_key_extract) void semanage_user_key_free(semanage_user_key_t * key) { sepol_user_key_free(key); } hidden_def(semanage_user_key_free) hidden void semanage_user_key_unpack(const semanage_user_key_t * key, const char **name) { sepol_user_key_unpack(key, name); } int semanage_user_compare(const semanage_user_t * user, const semanage_user_key_t * key) { const char *name; sepol_user_key_unpack(key, &name); return strcmp(user->name, name); } hidden_def(semanage_user_compare) int semanage_user_compare2(const semanage_user_t * user, const semanage_user_t * user2) { return strcmp(user->name, user2->name); } hidden_def(semanage_user_compare2) static int semanage_user_compare2_qsort(const semanage_user_t ** user, const semanage_user_t ** user2) { return strcmp((*user)->name, (*user2)->name); } /* Name */ const char *semanage_user_get_name(const semanage_user_t * user) { return user->name; } hidden_def(semanage_user_get_name) int semanage_user_set_name(semanage_handle_t * handle, semanage_user_t * user, const char *name) { char *tmp_name = strdup(name); if (!tmp_name) goto omem; if (semanage_user_base_set_name(handle, user->base, name) < 0) goto err; if (semanage_user_extra_set_name(handle, user->extra, name) < 0) goto err; free(user->name); user->name = tmp_name; return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: ERR(handle, "could not set user name to %s", name); free(tmp_name); return STATUS_ERR; } hidden_def(semanage_user_set_name) /* Labeling prefix */ const char *semanage_user_get_prefix(const semanage_user_t * user) { return semanage_user_extra_get_prefix(user->extra); } int semanage_user_set_prefix(semanage_handle_t * handle, semanage_user_t * user, const char *name) { return semanage_user_extra_set_prefix(handle, user->extra, name); } /* MLS */ const char *semanage_user_get_mlslevel(const semanage_user_t * user) { return semanage_user_base_get_mlslevel(user->base); } hidden_def(semanage_user_get_mlslevel) int semanage_user_set_mlslevel(semanage_handle_t * handle, semanage_user_t * user, const char *mls_level) { return semanage_user_base_set_mlslevel(handle, user->base, mls_level); } hidden_def(semanage_user_set_mlslevel) const char *semanage_user_get_mlsrange(const semanage_user_t * user) { return semanage_user_base_get_mlsrange(user->base); } hidden_def(semanage_user_get_mlsrange) int semanage_user_set_mlsrange(semanage_handle_t * handle, semanage_user_t * user, const char *mls_range) { return semanage_user_base_set_mlsrange(handle, user->base, mls_range); } hidden_def(semanage_user_set_mlsrange) /* Role management */ int semanage_user_get_num_roles(const semanage_user_t * user) { return semanage_user_base_get_num_roles(user->base); } int semanage_user_add_role(semanage_handle_t * handle, semanage_user_t * user, const char *role) { return semanage_user_base_add_role(handle, user->base, role); } hidden_def(semanage_user_add_role) void semanage_user_del_role(semanage_user_t * user, const char *role) { semanage_user_base_del_role(user->base, role); } int semanage_user_has_role(const semanage_user_t * user, const char *role) { return semanage_user_base_has_role(user->base, role); } int semanage_user_get_roles(semanage_handle_t * handle, const semanage_user_t * user, const char ***roles_arr, unsigned int *num_roles) { return semanage_user_base_get_roles(handle, user->base, roles_arr, num_roles); } hidden_def(semanage_user_get_roles) int semanage_user_set_roles(semanage_handle_t * handle, semanage_user_t * user, const char **roles_arr, unsigned int num_roles) { return semanage_user_base_set_roles(handle, user->base, roles_arr, num_roles); } /* Create/Clone/Destroy */ int semanage_user_create(semanage_handle_t * handle, semanage_user_t ** user_ptr) { semanage_user_t *tmp_user = calloc(1, sizeof(semanage_user_t)); if (!tmp_user) goto omem; if (semanage_user_base_create(handle, &tmp_user->base) < 0) goto err; if (semanage_user_extra_create(handle, &tmp_user->extra) < 0) goto err; /* Initialize the prefix for migration purposes */ if (semanage_user_extra_set_prefix(handle, tmp_user->extra, "user") < 0) goto err; *user_ptr = tmp_user; return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: ERR(handle, "could not create user record"); semanage_user_free(tmp_user); return STATUS_ERR; } hidden_def(semanage_user_create) int semanage_user_clone(semanage_handle_t * handle, const semanage_user_t * user, semanage_user_t ** user_ptr) { semanage_user_t *tmp_user = calloc(1, sizeof(semanage_user_t)); if (!tmp_user) goto omem; /* Clone base and extra records */ if (semanage_user_base_clone(handle, user->base, &tmp_user->base) < 0) goto err; if (semanage_user_extra_clone(handle, user->extra, &tmp_user->extra) < 0) goto err; /* Set the shared name */ if (semanage_user_set_name(handle, tmp_user, user->name) < 0) goto err; *user_ptr = tmp_user; return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: ERR(handle, "could not clone user record"); semanage_user_free(tmp_user); return STATUS_ERR; } hidden_def(semanage_user_clone) void semanage_user_free(semanage_user_t * user) { if (!user) return; semanage_user_base_free(user->base); semanage_user_extra_free(user->extra); free(user->name); free(user); } hidden_def(semanage_user_free) /* Join properties */ hidden int semanage_user_join(semanage_handle_t * handle, const semanage_user_base_t * record1, const semanage_user_extra_t * record2, semanage_user_t ** result) { const char *name; semanage_user_t *tmp_user = calloc(1, sizeof(semanage_user_t)); if (!tmp_user) goto omem; /* Set the shared name from one of the records * (at least one is available) */ if (record1 == NULL) name = semanage_user_extra_get_name(record2); else name = semanage_user_base_get_name(record1); /* Join base record if it exists, create a blank one otherwise */ if (record1) { if (semanage_user_base_clone(handle, record1, &tmp_user->base) < 0) goto err; } else { if (semanage_user_base_create(handle, &tmp_user->base) < 0) goto err; if (semanage_user_base_set_name(handle, tmp_user->base, name) < 0) goto err; } /* Join extra record if it exists, create a blank one otherwise */ if (record2) { if (semanage_user_extra_clone(handle, record2, &tmp_user->extra) < 0) goto err; } else { if (semanage_user_extra_create(handle, &tmp_user->extra) < 0) goto err; if (semanage_user_extra_set_name(handle, tmp_user->extra, name) < 0) goto err; if (semanage_user_extra_set_prefix (handle, tmp_user->extra, "user") < 0) goto err; } if (semanage_user_set_name(handle, tmp_user, name) < 0) goto err; *result = tmp_user; return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: ERR(handle, "could not join data records for user %s", semanage_user_base_get_name(record1)); semanage_user_free(tmp_user); return STATUS_ERR; } hidden int semanage_user_split(semanage_handle_t * handle, const semanage_user_t * record, semanage_user_base_t ** split1, semanage_user_extra_t ** split2) { semanage_user_base_t *tmp_base_user = NULL; semanage_user_extra_t *tmp_extra_user = NULL; if (semanage_user_base_clone(handle, record->base, &tmp_base_user) < 0) goto err; if (semanage_user_extra_clone(handle, record->extra, &tmp_extra_user) < 0) goto err; *split1 = tmp_base_user; *split2 = tmp_extra_user; return STATUS_SUCCESS; err: ERR(handle, "could not split data records for user %s", semanage_user_get_name(record)); semanage_user_base_free(tmp_base_user); semanage_user_extra_free(tmp_extra_user); return STATUS_ERR; } /* Record base functions */ record_table_t SEMANAGE_USER_RTABLE = { .create = semanage_user_create, .key_extract = semanage_user_key_extract, .key_free = semanage_user_key_free, .clone = semanage_user_clone, .compare = semanage_user_compare, .compare2 = semanage_user_compare2, .compare2_qsort = semanage_user_compare2_qsort, .free = semanage_user_free, }; libsemanage-2.3/src/users_base_file.c000066400000000000000000000115551233221606300177170ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_user_base; struct semanage_user_key; typedef struct semanage_user_base record_t; typedef struct semanage_user_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_file; typedef struct dbase_file dbase_t; #define DBASE_DEFINED #include #include #include #include #include #include "user_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" static int user_base_print(semanage_handle_t * handle, semanage_user_base_t * user, FILE * str) { const char **roles = NULL; unsigned int i, nroles; const char *name = semanage_user_base_get_name(user); const char *mls_level = semanage_user_base_get_mlslevel(user); const char *mls_range = semanage_user_base_get_mlsrange(user); if (fprintf(str, "user %s roles { ", name) < 0) goto err; if (semanage_user_base_get_roles(handle, user, &roles, &nroles) < 0) goto err; for (i = 0; i < nroles; i++) { if (fprintf(str, "%s ", roles[i]) < 0) goto err; } if (fprintf(str, "} ") < 0) goto err; /* MLS */ if (mls_level != NULL && mls_range != NULL) if (fprintf(str, "level %s range %s", mls_level, mls_range) < 0) goto err; if (fprintf(str, ";\n") < 0) goto err; free(roles); return STATUS_SUCCESS; err: free(roles); ERR(handle, "could not print user %s to stream", name); return STATUS_ERR; } static int user_base_parse(semanage_handle_t * handle, parse_info_t * info, semanage_user_base_t * user) { int islist = 0; char *str = NULL; char *start; char *name_str = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (!info->ptr) goto last; /* Parse user header */ if (parse_assert_str(handle, info, "user") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* Parse user name */ if (parse_fetch_string(handle, info, &name_str, ' ') < 0) goto err; if (semanage_user_base_set_name(handle, user, name_str) < 0) { free(name_str); goto err; } free(name_str); if (parse_assert_space(handle, info) < 0) goto err; if (parse_assert_str(handle, info, "roles") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; islist = (parse_optional_ch(info, '{') != STATUS_NODATA); /* For each role, loop */ do { char delim; if (parse_skip_space(handle, info) < 0) goto err; if (parse_assert_noeof(handle, info) < 0) goto err; start = info->ptr; while (*(info->ptr) && *(info->ptr) != ';' && *(info->ptr) != '}' && !isspace(*(info->ptr))) info->ptr++; delim = *(info->ptr); *(info->ptr)++ = '\0'; if (semanage_user_base_add_role(handle, user, start) < 0) goto err; if (delim && !isspace(delim)) { if (islist && delim == '}') break; else if (!islist && delim == ';') goto skip_semicolon; else goto err; } if (parse_skip_space(handle, info) < 0) goto err; if (parse_optional_ch(info, ';') != STATUS_NODATA) goto skip_semicolon; if (parse_optional_ch(info, '}') != STATUS_NODATA) islist = 0; } while (islist); /* Handle mls */ /* Parse level header */ if (parse_skip_space(handle, info) < 0) goto err; if (parse_optional_str(info, "level") == STATUS_NODATA) goto semicolon; if (parse_assert_space(handle, info) < 0) goto err; /* NOTE: does not allow spaces/multiline */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_user_base_set_mlslevel(handle, user, str) < 0) goto err; free(str); str = NULL; /* Parse range header */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_assert_str(handle, info, "range") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* NOTE: does not allow spaces/multiline */ if (parse_fetch_string(handle, info, &str, ';') < 0) goto err; if (semanage_user_base_set_mlsrange(handle, user, str) < 0) goto err; free(str); str = NULL; /* Check for semicolon */ semicolon: if (parse_skip_space(handle, info) < 0) goto err; if (parse_assert_ch(handle, info, ';') < 0) goto err; skip_semicolon: return STATUS_SUCCESS; last: parse_dispose_line(info); return STATUS_NODATA; err: ERR(handle, "could not parse user record"); free(str); parse_dispose_line(info); return STATUS_ERR; } /* USER BASE record: FILE extension: method table */ record_file_table_t SEMANAGE_USER_BASE_FILE_RTABLE = { .parse = user_base_parse, .print = user_base_print, }; int user_base_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig) { if (dbase_file_init(handle, fname, &SEMANAGE_USER_BASE_RTABLE, &SEMANAGE_USER_BASE_FILE_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_FILE_DTABLE; return STATUS_SUCCESS; } void user_base_file_dbase_release(dbase_config_t * dconfig) { dbase_file_release(dconfig->dbase); } libsemanage-2.3/src/users_base_policydb.c000066400000000000000000000041471233221606300206040ustar00rootroot00000000000000/* * Copyright (C) 2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_user_base; struct semanage_user_key; typedef struct semanage_user_base record_t; typedef struct semanage_user_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_policydb; typedef struct dbase_policydb dbase_t; #define DBASE_DEFINED #include #include #include "user_internal.h" #include "debug.h" #include "database_policydb.h" /* USER BASE record: POLICYDB extension: method table */ record_policydb_table_t SEMANAGE_USER_BASE_POLICYDB_RTABLE = { .add = NULL, .modify = (record_policydb_table_modify_t) sepol_user_modify, .set = NULL, .query = (record_policydb_table_query_t) sepol_user_query, .count = (record_policydb_table_count_t) sepol_user_count, .exists = (record_policydb_table_exists_t) sepol_user_exists, .iterate = (record_policydb_table_iterate_t) sepol_user_iterate, }; int user_base_policydb_dbase_init(semanage_handle_t * handle, dbase_config_t * dconfig) { if (dbase_policydb_init(handle, "policy.kern", &SEMANAGE_USER_BASE_RTABLE, &SEMANAGE_USER_BASE_POLICYDB_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE; return STATUS_SUCCESS; } void user_base_policydb_dbase_release(dbase_config_t * dconfig) { dbase_policydb_release(dconfig->dbase); } libsemanage-2.3/src/users_extra_file.c000066400000000000000000000054321233221606300201250ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_user_extra; struct semanage_user_key; typedef struct semanage_user_extra record_t; typedef struct semanage_user_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_file; typedef struct dbase_file dbase_t; #define DBASE_DEFINED #include #include #include #include "user_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" #include "handle.h" static int user_extra_print(semanage_handle_t * handle, semanage_user_extra_t * user_extra, FILE * str) { const char *name = semanage_user_extra_get_name(user_extra); const char *prefix = semanage_user_extra_get_prefix(user_extra); if (fprintf(str, "user %s prefix %s;\n", name, prefix) < 0) goto err; return STATUS_SUCCESS; err: ERR(handle, "could not print user extra data " "for %s to stream", name); return STATUS_ERR; } static int user_extra_parse(semanage_handle_t * handle, parse_info_t * info, semanage_user_extra_t * user_extra) { char *str = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (!info->ptr) goto last; /* User string */ if (parse_assert_str(handle, info, "user") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* Extract name */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_user_extra_set_name(handle, user_extra, str) < 0) goto err; free(str); str = NULL; /* Prefix string */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_assert_str(handle, info, "prefix") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* Extract prefix */ if (parse_fetch_string(handle, info, &str, ';') < 0) goto err; if (semanage_user_extra_set_prefix(handle, user_extra, str) < 0) goto err; free(str); str = NULL; /* Semicolon */ if (parse_skip_space(handle, info) < 0) goto err; if (parse_assert_ch(handle, info, ';') < 0) goto err; return STATUS_SUCCESS; last: parse_dispose_line(info); return STATUS_NODATA; err: ERR(handle, "could not parse user extra data"); free(str); parse_dispose_line(info); return STATUS_ERR; } /* USER EXTRA RECORD: FILE extension: method table */ record_file_table_t SEMANAGE_USER_EXTRA_FILE_RTABLE = { .parse = user_extra_parse, .print = user_extra_print, }; int user_extra_file_dbase_init(semanage_handle_t * handle, const char *fname, dbase_config_t * dconfig) { if (dbase_file_init(handle, fname, &SEMANAGE_USER_EXTRA_RTABLE, &SEMANAGE_USER_EXTRA_FILE_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_FILE_DTABLE; return STATUS_SUCCESS; } void user_extra_file_dbase_release(dbase_config_t * dconfig) { dbase_file_release(dconfig->dbase); } libsemanage-2.3/src/users_join.c000066400000000000000000000022461233221606300167420ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_user; struct semanage_user_key; typedef struct semanage_user record_t; typedef struct semanage_user_key record_key_t; #define DBASE_RECORD_DEFINED struct semanage_user_base; struct semanage_user_extra; typedef struct semanage_user_base record1_t; typedef struct semanage_user_extra record2_t; #define DBASE_RECORD_JOIN_DEFINED struct dbase_join; typedef struct dbase_join dbase_t; #define DBASE_DEFINED #include #include "user_internal.h" #include "database_join.h" #include "debug.h" /* USER record: JOIN extension: method table */ record_join_table_t SEMANAGE_USER_JOIN_RTABLE = { .join = semanage_user_join, .split = semanage_user_split, }; int user_join_dbase_init(semanage_handle_t * handle, dbase_config_t * join1, dbase_config_t * join2, dbase_config_t * dconfig) { if (dbase_join_init(handle, &SEMANAGE_USER_RTABLE, &SEMANAGE_USER_JOIN_RTABLE, join1, join2, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_JOIN_DTABLE; return STATUS_SUCCESS; } void user_join_dbase_release(dbase_config_t * dconfig) { dbase_join_release(dconfig->dbase); } libsemanage-2.3/src/users_local.c000066400000000000000000000055321233221606300170760ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ struct semanage_user; struct semanage_user_key; typedef struct semanage_user_key record_key_t; typedef struct semanage_user record_t; #define DBASE_RECORD_DEFINED #include #include #include "user_internal.h" #include "seuser_internal.h" #include "handle.h" #include "database.h" #include "errno.h" #include "debug.h" int semanage_user_modify_local(semanage_handle_t * handle, const semanage_user_key_t * key, const semanage_user_t * data) { dbase_config_t *dconfig = semanage_user_dbase_local(handle); return dbase_modify(handle, dconfig, key, data); } static int lookup_seuser(semanage_handle_t * handle, const semanage_user_key_t *k) { semanage_user_t *user; semanage_seuser_t **records; const char *name; const char *sename; unsigned int count; size_t i; int rc = 0; if (semanage_user_query(handle, k, &user) < 0) return 0; name = semanage_user_get_name(user); semanage_seuser_list_local(handle, &records, &count); for(i=0; i * Paul Rosenfeld * * Copyright (C) 2007 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "utilities.h" #include #include #include #include #include #include #include #include #define TRUE 1 #define FALSE 0 char *semanage_findval(char *file, char *var, char *delim) { FILE *fd; char *buff = NULL; char *retval = NULL; size_t buff_len = 0; assert(file); assert(var); if ((fd = fopen(file, "r")) == NULL) return NULL; while (getline(&buff, &buff_len, fd) > 0) { if (semanage_is_prefix(buff, var)) { retval = semanage_split(buff, delim); if (retval) semanage_rtrim(retval, '\n'); break; } } free(buff); fclose(fd); return retval; } int semanage_is_prefix(const char *str, const char *prefix) { if (!str) { return FALSE; } if (!prefix) { return TRUE; } return strncmp(str, prefix, strlen(prefix)) == 0; } char *semanage_split_on_space(const char *str) { /* as per the man page, these are the isspace() chars */ const char *seps = "\f\n\r\t\v "; size_t slen = strlen(seps); size_t off = 0, rside_len = 0; char *retval = NULL; Ustr *ustr = USTR_NULL, *temp = USTR_NULL; if (!str) goto done; if (!(ustr = ustr_dup_cstr(str))) goto done; temp = ustr_split_spn_chrs(ustr, &off, seps, slen, USTR_NULL, USTR_FLAG_SPLIT_DEF); if (!temp) goto done; /* throw away the left hand side */ ustr_sc_free(&temp); rside_len = ustr_len(ustr) - off; temp = ustr_dup_subustr(ustr, off + 1, rside_len); if (!temp) goto done; retval = strdup(ustr_cstr(temp)); ustr_sc_free(&temp); done: ustr_sc_free(&ustr); return retval; } char *semanage_split(const char *str, const char *delim) { Ustr *ustr = USTR_NULL, *temp = USTR_NULL; size_t off = 0, rside_len = 0; char *retval = NULL; if (!str) goto done; if (!delim || !(*delim)) return semanage_split_on_space(str); ustr = ustr_dup_cstr(str); temp = ustr_split_cstr(ustr, &off, delim, USTR_NULL, USTR_FLAG_SPLIT_DEF); if (!temp) goto done; /* throw away the left hand side */ ustr_sc_free(&temp); rside_len = ustr_len(ustr) - off; temp = ustr_dup_subustr(ustr, off + 1, rside_len); if (!temp) goto done; retval = strdup(ustr_cstr(temp)); ustr_sc_free(&temp); done: ustr_sc_free(&ustr); return retval; } int semanage_list_push(semanage_list_t ** list, char *data) { semanage_list_t *temp = NULL; if (!data) return EINVAL; if (semanage_list_find(*list, data) != NULL) return 0; if (!(temp = malloc(sizeof(semanage_list_t)))) return ENOMEM; if (!(temp->data = strdup(data))) { free(temp); return ENOMEM; } temp->next = *list; *list = temp; return 0; } char *semanage_list_pop(semanage_list_t ** list) { semanage_list_t *node = NULL; char *data = NULL; if (!list || !(*list)) return NULL; node = (*list); data = node->data; (*list) = node->next; free(node); return data; } void semanage_list_destroy(semanage_list_t ** list) { semanage_list_t *temp; while ((temp = (*list))) { free(temp->data); (*list) = temp->next; free(temp); } } semanage_list_t *semanage_list_find(semanage_list_t * l, char *data) { if (!data) return NULL; while (l && strcmp(l->data, data)) l = l->next; return l; } int semanage_list_sort(semanage_list_t ** l) { semanage_list_t **array = NULL; semanage_list_t *temp = NULL; size_t count = 0; size_t i = 0; if (!l) return 0; for (temp = *l; temp; temp = temp->next) ++count; array = malloc(sizeof(semanage_list_t *) * count); if (!array) return ENOMEM; /* couldn't allocate memory for sort */ for (temp = *l; temp; temp = temp->next) { array[i++] = temp; } qsort(array, count, sizeof(semanage_list_t *), (int (*)(const void *, const void *))&semanage_cmp_plist_t); for (i = 0; i < (count - 1); ++i) { array[i]->next = array[i + 1]; } array[i]->next = NULL; (*l) = array[0]; free(array); return 0; } int semanage_cmp_plist_t(const semanage_list_t ** x, const semanage_list_t ** y) { return strcmp((*x)->data, (*y)->data); } int semanage_str_count(char *data, char what) { int count = 0; if (!data) return 0; while (*data) { if (*data == what) ++count; ++data; } return count; } void semanage_rtrim(char *str, char trim_to) { int len = 0; if (!str) return; len = strlen(str); while (len > 0) { if (str[--len] == trim_to) { str[len] = '\0'; return; } } } /* list_addafter_controlmem does *NOT* duplicate the data argument * use at your own risk, I am building a list out of malloc'd memory and * it is only going to get stored into this list, thus when I destroy it * later I won't free a ptr twice. * * returns the newly created node or NULL on error */ semanage_list_t *list_addafter_controlmem(semanage_list_t * item, char *data) { semanage_list_t *temp = malloc(sizeof(semanage_list_t)); if (!temp) return NULL; temp->data = data; temp->next = item->next; item->next = temp; return temp; } semanage_list_t *semanage_slurp_file_filter(FILE * file, int (*pred) (const char *)) { semanage_list_t head; semanage_list_t *current = &head; char *line = NULL; size_t buff_len = 0; head.next = NULL; /* initialize head, we aren't going to use the data */ while (getline(&line, &buff_len, file) >= 0) { if (pred(line)) { semanage_rtrim(line, '\n'); current = list_addafter_controlmem(current, line); if (!current) break; line = NULL; buff_len = 0; } } free(line); return head.next; } libsemanage-2.3/src/utilities.h000066400000000000000000000114721233221606300166030ustar00rootroot00000000000000/* Author: Mark Goldman * * Copyright (C) 2007 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* This file contains helper functions that are loosely based off of what is * available from the python script genhomedircon. Also this file contains * c implementations of a couple of python functions so that genhomedircon will * look/act like the python script. */ #ifndef _SEMANAGE_UTILITIES_H_ #define _SEMANAGE_UTILITIES_H_ #include #if defined(__GNUC__) && !defined(__STRICT_ANSI__) #define WARN_UNUSED \ __attribute__ ((__warn_unused_result__)) #else # define WARN_UNUSED /* nothing */ #endif typedef struct list { char *data; struct list *next; } semanage_list_t; /** * @param file the path to the file to look for a variable in * @param var the variable that you want the value of * @param delim the value that separates the part you care about from the part * that you don't. * @return for the first instance of var in the file, returns everything after * delim. * returns "" if not found IE if(*(semanage_findval(f,v,d)) == '\0'){ * printf("%s not found in file", v); * } * * NULL for error (out of memory, etc) */ char *semanage_findval(char *file, char *var, char *delim) WARN_UNUSED; /** * @param str string to test * @param val prefix * @return 1 if val is the prefix of str * 0 if val is not the prefix of str * * note: if str == NULL, returns false * if val == NULL, returns true --nothing can always be the prefix of * something * if (*val) == "" returns true same as above. */ int semanage_is_prefix(const char *str, const char *val) WARN_UNUSED; /** * @param str the string to semanage_split * @return malloc'd string after the first run of charachters that aren't whitespace */ char *semanage_split_on_space(const char *str) WARN_UNUSED; /** * @param str the string to semanage_split * @param delim the string delimiter. NOT a set of charachters that can be * a delimiter. * if *delim == '\0' behaves as semanage_splitOnSpace() * @return a ptr to the first charachter past the delimiter. * if delim doesn't appear in the string, returns a ptr to the * trailing null in the string */ char *semanage_split(const char *str, const char *delim) WARN_UNUSED; /* linked list string functions * Functions allocate memory. Must be free'd with * either semanage_list_pop until list == NULL or semanage_list_destroy() */ int semanage_list_push(semanage_list_t ** list, char *data) WARN_UNUSED; char *semanage_list_pop(semanage_list_t ** list); void semanage_list_destroy(semanage_list_t ** list); semanage_list_t *semanage_list_find(semanage_list_t * l, char *data) WARN_UNUSED; int semanage_list_sort(semanage_list_t ** l) WARN_UNUSED; /* function to compare 2 semanage_list_t nodes, * returns strcmp(x->data, y->data) * used internally by semanage_list_sort() */ int semanage_cmp_plist_t(const semanage_list_t ** x, const semanage_list_t ** y); /** * @param data a target string * @param what a charachter * @returns the number of times the char appears in the string */ int semanage_str_count(char *data, char what); /** * @param - a string * @param the charachter to trim to * @return - mangles the string, converting the first * occurrance of the charachter to a '\0' from * the end of the string. */ void semanage_rtrim(char *str, char trim_to); /** * @param data some string * @return modifies the string such that the first whitespace char becomes * '\0', ending the string. */ void semanage_keep_until_space(char *data); /** * @param file - an open FILE to read from * @param pred - a function taking a string that * returns 1 if the string should be * kept and 0 otherwise * @return a list of lines from the file (empty lines become * empty strings) in the file order where pred(line) * returns > 0 */ semanage_list_t *semanage_slurp_file_filter(FILE * file, int (*pred) (const char *)) WARN_UNUSED; #endif libsemanage-2.3/tests/000077500000000000000000000000001233221606300147655ustar00rootroot00000000000000libsemanage-2.3/tests/Makefile000066400000000000000000000015261233221606300164310ustar00rootroot00000000000000# Add your test source files here: SOURCES = $(wildcard *.c) # Point this variable to the libsemanage source directory you want to test: TESTSRC=../src # Add the required external object files here: LIBS = ../src/libsemanage.a ../../libselinux/src/libselinux.a ../../libsepol/src/libsepol.a ########################################################################### EXECUTABLE = libsemanage-tests CC = gcc CFLAGS = -c -g -o0 -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute -Wno-unused-parameter INCLUDE = -I$(TESTSRC) -I$(TESTSRC)/../include LDFLAGS = -lcunit -lustr -lbz2 -laudit OBJECTS = $(SOURCES:.c=.o) all: $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS) $(CC) $(OBJECTS) $(LIBS) $(LDFLAGS) -o $@ %.o: %.c $(CC) $(CFLAGS) $(INCLUDE) $*.c -o $*.o clean distclean: rm -rf $(OBJECTS) $(EXECUTABLE) test: all ./$(EXECUTABLE) libsemanage-2.3/tests/README000066400000000000000000000044101233221606300156440ustar00rootroot00000000000000Notes on tests ============================ The semanage_access_check test in the semanage_store suite simulates a read-only filesystem by using DAC permissions. Consequently, these tests will fail if run as root, as root can override DAC permissions. How to add and use unit tests ============================= We are using the CUnit unit testing framework. This framework--and the official documentation of the framework--may be found here: http://cunit.sourceforge.net/ If you have not yet installed CUnit, first do that. (There is an RPM, or you can compile from source.) Once installed, follow these steps to add unit tests for your code: 1. Create a .h and .c file corresponding to the .c file you want to test. For example, test_semanage_store.c provides tests of the functions in semanage_store.c. Your new .h/.c files represent a suite of related tests. 2. Write or add new tests to a suite. Tests are simply functions that take the form: void test_my_function(void) These tests are where you will make calls to the CUnit assertions. If you are making a new test suite, also add the suite init/cleanup functions. These take the form: int _test_init(void) int _cleanup(void) These functions will be called before and after the test functions in your suite, respectively. They return 0 on success, 1 on failure. 3. Update libsemanage-tests.c to add your new suite and/or your new tests using the DECLARE_SUITE macro in do_tests(). 4. Update the Makefile: + Make sure that the TESTSRC variable is set to the location of the libsemanage source code you want to test. 5. Compile the libsemanage source code you will be testing, to ensure the object files are available and up to date. 6. Run your tests. Rejoice or despair, as appropriate. A note on the the utilities.c: Add functions that can be commonly used here. For example, it is handy to have a dummy message callback function to silence error messages produced by libsemanage and keep your output pretty. To do this, include utilities.h and specify the callback like so: semanage_handle_t *sh; sh = semanage_handle_create(); sh->msg_callback = test_msg_handler; Feel free to add other such functions here as well. libsemanage-2.3/tests/libsemanage-tests.c000066400000000000000000000052741233221606300205500ustar00rootroot00000000000000/* Authors: Christopher Ashworth * Caleb Case * Chad Sellers * * Copyright (C) 2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "test_semanage_store.h" #include "test_utilities.h" #include #include #include #include #include #include #define DECLARE_SUITE(name) \ suite = CU_add_suite(#name, name##_test_init, name##_test_cleanup); \ if (NULL == suite) { \ CU_cleanup_registry(); \ return CU_get_error(); } \ if (name##_add_tests(suite)) { \ CU_cleanup_registry(); \ return CU_get_error(); } static void usage(char *progname) { printf("usage: %s [options]\n", progname); printf("options:\n"); printf("\t-v, --verbose\t\t\tverbose output\n"); printf("\t-i, --interactive\t\tinteractive console\n"); } static int do_tests(int interactive, int verbose) { CU_pSuite suite = NULL; /* Initialize the CUnit test registry. */ if (CUE_SUCCESS != CU_initialize_registry()) return CU_get_error(); DECLARE_SUITE(semanage_store); DECLARE_SUITE(semanage_utilities); if (verbose) CU_basic_set_mode(CU_BRM_VERBOSE); else CU_basic_set_mode(CU_BRM_NORMAL); if (interactive) CU_console_run_tests(); else CU_basic_run_tests(); CU_cleanup_registry(); return CU_get_error(); } /* The main function for setting up and running the libsemanage unit tests. * Returns a CUE_SUCCESS on success, or a CUnit error code on failure. */ int main(int argc, char **argv) { int i, verbose = 1, interactive = 0; struct option opts[] = { {"verbose", 0, NULL, 'v'}, {"interactive", 0, NULL, 'i'}, {NULL, 0, NULL, 0} }; while ((i = getopt_long(argc, argv, "vi", opts, NULL)) != -1) { switch (i) { case 'v': verbose = 1; break; case 'i': interactive = 1; break; case 'h': default:{ usage(argv[0]); exit(1); } } } if (do_tests(interactive, verbose)) return -1; return 0; } libsemanage-2.3/tests/nc_sort_malformed000066400000000000000000000022161233221606300204060ustar00rootroot00000000000000pre *mangle pre :PREROUTING ACCEPT [0:0] pre :INPUT ACCEPT [0:0] pre :FORWARD ACCEPT [0:0] pre :OUTPUT ACCEPT [0:0] pre :POSTROUTING ACCEPT [0:0] pre :selinux_input - [0:0] pre :selinux_output - [0:0] pre :selinux_new_input - [0:0] pre :selinux_new_output - [0:0] pre -A INPUT -j selinux_input pre -A OUTPUT -j selinux_output pre -A selinux_input -m state --state NEW -j selinux_new_input pre -A selinux_input -m state --state RELATED,ESTABLISHED -j CONNSECMARK --restore pre -A selinux_output -m state --state NEW -j selinux_new_output pre -A selinux_output -m state --state RELATED,ESTABLISHED -j CONNSECMARK --restore pre -A selinux_new_input -j SECMARK --selctx system_u:object_r:server_packet_t base -A selinux_new_input -p tcp --dport 80 -j SECMARK --selctx system_u:object_r:http_server_packet_t -A selinux_new_input -j CONNSECMARK --save post -A selinux_new_input -j RETURN pre -A selinux_new_output -j SECMARK --selctx system_u:object_r:client_packet_t module -A selinux_new_output -p tcp --dport 80 -j SECMARK --selctx system_u:object_r:http_client_packet_t post -A selinux_new_output -j CONNSECMARK --save post -A selinux_new_output -j RETURN post COMMIT libsemanage-2.3/tests/nc_sort_sorted000066400000000000000000000020461233221606300177410ustar00rootroot00000000000000*mangle :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] :selinux_input - [0:0] :selinux_output - [0:0] :selinux_new_input - [0:0] :selinux_new_output - [0:0] -A INPUT -j selinux_input -A OUTPUT -j selinux_output -A selinux_input -m state --state NEW -j selinux_new_input -A selinux_input -m state --state RELATED,ESTABLISHED -j CONNSECMARK --restore -A selinux_output -m state --state NEW -j selinux_new_output -A selinux_output -m state --state RELATED,ESTABLISHED -j CONNSECMARK --restore -A selinux_new_input -j SECMARK --selctx system_u:object_r:server_packet_t -A selinux_new_output -j SECMARK --selctx system_u:object_r:client_packet_t -A selinux_new_input -p tcp --dport 80 -j SECMARK --selctx system_u:object_r:http_server_packet_t -A selinux_new_output -p tcp --dport 80 -j SECMARK --selctx system_u:object_r:http_client_packet_t -A selinux_new_input -j CONNSECMARK --save -A selinux_new_input -j RETURN -A selinux_new_output -j CONNSECMARK --save -A selinux_new_output -j RETURN COMMIT libsemanage-2.3/tests/nc_sort_unsorted000066400000000000000000000022651233221606300203070ustar00rootroot00000000000000pre *mangle pre :PREROUTING ACCEPT [0:0] pre :INPUT ACCEPT [0:0] pre :FORWARD ACCEPT [0:0] pre :OUTPUT ACCEPT [0:0] pre :POSTROUTING ACCEPT [0:0] pre :selinux_input - [0:0] pre :selinux_output - [0:0] pre :selinux_new_input - [0:0] pre :selinux_new_output - [0:0] # a comment pre -A INPUT -j selinux_input pre -A OUTPUT -j selinux_output pre -A selinux_input -m state --state NEW -j selinux_new_input pre -A selinux_input -m state --state RELATED,ESTABLISHED -j CONNSECMARK --restore pre -A selinux_output -m state --state NEW -j selinux_new_output # another comment pre -A selinux_output -m state --state RELATED,ESTABLISHED -j CONNSECMARK --restore base-A selinux_new_input -j SECMARK --selctx system_u:object_r:server_packet_t module -A selinux_new_input -p tcp --dport 80 -j SECMARK --selctx system_u:object_r:http_server_packet_t post -A selinux_new_input -j CONNSECMARK --save post -A selinux_new_input -j RETURN base -A selinux_new_output -j SECMARK --selctx system_u:object_r:client_packet_t module -A selinux_new_output -p tcp --dport 80 -j SECMARK --selctx system_u:object_r:http_client_packet_t post -A selinux_new_output -j CONNSECMARK --save post -A selinux_new_output -j RETURN post COMMIT libsemanage-2.3/tests/test_semanage_store.c000066400000000000000000000220641233221606300211700ustar00rootroot00000000000000/* Authors: Christopher Ashworth * Caleb Case * Chris PeBenito * * Copyright (C) 2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* The purpose of this file is to provide unit tests of the functions in: * * libsemanage/src/semanage_store.c * */ #include "handle.h" #include "semanage_store.h" #include "utilities.h" #include "test_semanage_store.h" #include #include #include #include #include #include #include #include #include #include #include semanage_handle_t *sh = NULL; const char *polpath = "./test-policy"; const char *lockpath = "./test-policy/modules"; const char *readlockpath = "./test-policy/modules/semanage.read.LOCK"; const char *translockpath = "./test-policy/modules/semanage.trans.LOCK"; const char *actpath = "./test-policy/modules/active"; const char *modpath = "./test-policy/modules/active/modules"; /* The suite initialization function. * Returns zero on success, non-zero otherwise. */ int semanage_store_test_init(void) { int err; /* create directories */ err = mkdir(polpath, S_IRUSR | S_IWUSR | S_IXUSR); if (err != 0) return -1; err = mkdir(lockpath, S_IRUSR | S_IWUSR | S_IXUSR); if (err != 0) return -1; err = mkdir(actpath, S_IRUSR | S_IWUSR | S_IXUSR); if (err != 0) return -1; err = mkdir(modpath, S_IRUSR | S_IWUSR | S_IXUSR); if (err != 0) return -1; /* initialize the handle */ sh = semanage_handle_create(); if (sh == NULL) return -1; /* hide error messages */ sh->msg_callback = test_msg_handler; /* initialize paths */ err = semanage_check_init(polpath); if (err != 0) return -1; return 0; } /* The suite cleanup function. * Returns zero on success, non-zero otherwise. */ int semanage_store_test_cleanup(void) { int err; /* remove the test policy directories */ err = rmdir(modpath); if (err != 0) return -1; err = rmdir(actpath); if (err != 0) return -1; err = rmdir(lockpath); if (err != 0) return -1; err = rmdir(polpath); if (err != 0) return -1; /* cleanup the handle */ semanage_handle_destroy(sh); return 0; } /* Adds all the tests needed for this suite. */ int semanage_store_add_tests(CU_pSuite suite) { if (NULL == CU_add_test(suite, "semanage_store_access_check", test_semanage_store_access_check)) { CU_cleanup_registry(); return CU_get_error(); } if (NULL == CU_add_test(suite, "semanage_get_lock", test_semanage_get_lock)) { CU_cleanup_registry(); return CU_get_error(); } if (NULL == CU_add_test(suite, "semanage_nc_sort", test_semanage_nc_sort)) { CU_cleanup_registry(); return CU_get_error(); } return 0; } /* Tests the semanage_store_access_check function in semanage_store.c */ void test_semanage_store_access_check(void) { int err; /* create lock file */ err = mknod(readlockpath, S_IRUSR | S_IWUSR, S_IFREG); /* check with permissions 000 */ err = chmod(modpath, 0); CU_ASSERT(err == 0); err = chmod(readlockpath, 0); CU_ASSERT(err == 0); err = chmod(polpath, 0); CU_ASSERT(err == 0); err = semanage_store_access_check(); CU_ASSERT(err == -1); /* check with permissions 500 */ err = chmod(polpath, S_IRUSR | S_IXUSR); CU_ASSERT(err == 0); err = chmod(readlockpath, S_IRUSR); CU_ASSERT(err == 0); err = chmod(modpath, S_IRUSR | S_IXUSR); CU_ASSERT(err == 0); err = semanage_store_access_check(); CU_ASSERT(err == SEMANAGE_CAN_READ); /* check with permissions 700 */ err = chmod(polpath, S_IRUSR | S_IWUSR | S_IXUSR); CU_ASSERT(err == 0); err = chmod(readlockpath, S_IRUSR | S_IWUSR); CU_ASSERT(err == 0); err = chmod(modpath, S_IRUSR | S_IWUSR | S_IXUSR); CU_ASSERT(err == 0); err = semanage_store_access_check(); CU_ASSERT(err == SEMANAGE_CAN_WRITE); /* check with lock file 000 and others 500 */ err = chmod(polpath, S_IRUSR | S_IXUSR); CU_ASSERT(err == 0); err = chmod(readlockpath, 0); CU_ASSERT(err == 0); err = chmod(modpath, S_IRUSR | S_IXUSR); CU_ASSERT(err == 0); err = semanage_store_access_check(); CU_ASSERT(err == 0); /* check with lock file 000 and others 700 */ err = chmod(polpath, S_IRUSR | S_IWUSR | S_IXUSR); CU_ASSERT(err == 0); err = chmod(readlockpath, 0); CU_ASSERT(err == 0); err = chmod(modpath, S_IRUSR | S_IWUSR | S_IXUSR); CU_ASSERT(err == 0); err = semanage_store_access_check(); CU_ASSERT(err == 0); /* remove lock file */ err = remove(readlockpath); CU_ASSERT(err == 0); /* check with no lock file and 000 */ err = chmod(modpath, 0); CU_ASSERT(err == 0); err = chmod(lockpath, 0); CU_ASSERT(err == 0); err = chmod(polpath, 0); CU_ASSERT(err == 0); err = semanage_store_access_check(); CU_ASSERT(err == -1); /* check with no lock file and 500 */ err = chmod(polpath, S_IRUSR | S_IXUSR); CU_ASSERT(err == 0); err = chmod(lockpath, S_IRUSR | S_IXUSR); CU_ASSERT(err == 0); err = chmod(modpath, S_IRUSR | S_IXUSR); CU_ASSERT(err == 0); err = semanage_store_access_check(); CU_ASSERT(err == 0); /* check with no lock file but write in lockpath */ err = chmod(lockpath, S_IRUSR | S_IWUSR | S_IXUSR); CU_ASSERT(err == 0); err = semanage_store_access_check(); CU_ASSERT(err == SEMANAGE_CAN_READ); /* check with no lock file and 700 */ err = chmod(polpath, S_IRUSR | S_IWUSR | S_IXUSR); CU_ASSERT(err == 0); err = chmod(modpath, S_IRUSR | S_IWUSR | S_IXUSR); CU_ASSERT(err == 0); err = semanage_store_access_check(); CU_ASSERT(err == SEMANAGE_CAN_WRITE); } /* Tests the semanage_get_lock functions in semanage_store.c */ void test_semanage_get_lock(void) { int err; /* attempt to get an active lock */ err = semanage_get_active_lock(sh); CU_ASSERT(err == 0); /* attempt to get the lock again */ err = semanage_get_active_lock(sh); CU_ASSERT(err == 0); /* attempt to release the active lock */ semanage_release_active_lock(sh); /* attempt to get an active lock */ err = semanage_get_active_lock(sh); CU_ASSERT(err == 0); /* attempt to release the active lock */ semanage_release_active_lock(sh); /* attempt to get a trans lock */ err = semanage_get_trans_lock(sh); CU_ASSERT(err == 0); /* attempt to get the lock again */ err = semanage_get_trans_lock(sh); CU_ASSERT(err == 0); /* attempt to release the trans lock */ semanage_release_trans_lock(sh); /* attempt to get a trans lock */ err = semanage_get_trans_lock(sh); CU_ASSERT(err == 0); /* attempt to release the trans lock */ semanage_release_trans_lock(sh); /* remove the lock files */ err = remove(readlockpath); CU_ASSERT(err == 0); err = remove(translockpath); CU_ASSERT(err == 0); } /* Tests the semanage_nc_sort function in semanage_store.c */ void test_semanage_nc_sort(void) { char *source_buf, *sorted_buf = NULL, *good_buf, *bad_buf; size_t source_buf_len, sorted_buf_len, good_buf_len, bad_buf_len; int sourcefd, goodfd, badfd, err; struct stat sb; /* open source file */ sourcefd = open("nc_sort_unsorted", O_RDONLY); if (sourcefd < 0) { CU_FAIL("Missing nc_sort_unsorted test file."); return; } fstat(sourcefd, &sb); source_buf_len = sb.st_size; source_buf = (char *)mmap(NULL, source_buf_len, PROT_READ, MAP_PRIVATE, sourcefd, 0); /* open good result file */ goodfd = open("nc_sort_sorted", O_RDONLY); if (goodfd < 0) { CU_FAIL("Missing nc_sort_sorted test file."); goto out2; } fstat(goodfd, &sb); good_buf_len = sb.st_size; good_buf = (char *)mmap(NULL, good_buf_len, PROT_READ, MAP_PRIVATE, goodfd, 0); /* open malformed source file (missing priorities) */ badfd = open("nc_sort_malformed", O_RDONLY); if (badfd < 0) { CU_FAIL("Missing nc_sort_malformed test file."); goto out1; } fstat(badfd, &sb); bad_buf_len = sb.st_size; bad_buf = (char *)mmap(NULL, bad_buf_len, PROT_READ, MAP_PRIVATE, badfd, 0); /* sort test file */ err = semanage_nc_sort(sh, source_buf, source_buf_len, &sorted_buf, &sorted_buf_len); CU_ASSERT_FALSE(err); CU_ASSERT_STRING_EQUAL(sorted_buf, good_buf); /* reset for reuse in next test */ free(sorted_buf); sorted_buf = NULL; /* sort malformed source file */ err = semanage_nc_sort(sh, bad_buf, bad_buf_len, &sorted_buf, &sorted_buf_len); CU_ASSERT_EQUAL(err, -1); free(sorted_buf); munmap(bad_buf, bad_buf_len); close(badfd); out1: munmap(good_buf, good_buf_len); close(goodfd); out2: munmap(source_buf, source_buf_len); close(sourcefd); } libsemanage-2.3/tests/test_semanage_store.h000066400000000000000000000023421233221606300211720ustar00rootroot00000000000000/* Authors: Christopher Ashworth * Chris PeBenito * * Copyright (C) 2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __TEST_SEMANAGE_STORE_H__ #define __TEST_SEMANAGE_STORE_H__ #include int semanage_store_test_init(void); int semanage_store_test_cleanup(void); int semanage_store_add_tests(CU_pSuite suite); void test_semanage_store_access_check(void); void test_semanage_get_lock(void); void test_semanage_nc_sort(void); #endif libsemanage-2.3/tests/test_utilities.c000066400000000000000000000156601233221606300202130ustar00rootroot00000000000000/* Authors: Mark Goldman * * Copyright (C) 2007 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* The purpose of this file is to provide unit tests of the functions in: * * libsemanage/src/utilities.c * */ #include #include #include #include #include #include #include #include #include void test_semanage_is_prefix(void); void test_semanage_split_on_space(void); void test_semanage_split(void); void test_semanage_list(void); void test_semanage_str_count(void); void test_semanage_rtrim(void); void test_semanage_findval(void); void test_slurp_file_filter(void); char fname[] = { 'T', 'E', 'S', 'T', '_', 'T', 'E', 'M', 'P', '_', 'X', 'X', 'X', 'X', 'X', 'X' }; int fd; FILE *fptr; int semanage_utilities_test_init(void) { fd = mkstemp(fname); if (fd < 0) { perror("test_semanage_findval: "); CU_FAIL_FATAL ("Error opening temporary file, test cannot start."); } fptr = fdopen(fd, "w+"); if (!fptr) { perror("test_semanage_findval file: "); CU_FAIL_FATAL("Error opening file stream, test cannot start."); } fprintf(fptr, "one\ntwo\nthree\nsigma=foo\n#boo\n#bar\n"); rewind(fptr); return 0; } int semanage_utilities_test_cleanup(void) { unlink(fname); return 0; } int semanage_utilities_add_tests(CU_pSuite suite) { if (NULL == CU_add_test(suite, "semanage_is_prefix", test_semanage_is_prefix)) { goto err; } if (NULL == CU_add_test(suite, "semanage_split_on_space", test_semanage_split_on_space)) { goto err; } if (NULL == CU_add_test(suite, "semanage_split", test_semanage_split)) { goto err; } if (NULL == CU_add_test(suite, "semanage_list", test_semanage_list)) { goto err; } if (NULL == CU_add_test(suite, "semanage_str_count", test_semanage_str_count)) { goto err; } if (NULL == CU_add_test(suite, "semanage_rtrim", test_semanage_rtrim)) { goto err; } if (NULL == CU_add_test(suite, "semanage_findval", test_semanage_findval)) { goto err; } if (NULL == CU_add_test(suite, "slurp_file_filter", test_slurp_file_filter)) { goto err; } return 0; err: CU_cleanup_registry(); return CU_get_error(); } void test_semanage_is_prefix(void) { char *str = "some string"; char *pre = "some"; char *not_pre = "not this"; CU_ASSERT_TRUE(semanage_is_prefix(str, pre)); CU_ASSERT_TRUE(semanage_is_prefix(str, "")); CU_ASSERT_TRUE(semanage_is_prefix(str, NULL)); CU_ASSERT_FALSE(semanage_is_prefix(str, not_pre)); } void test_semanage_split_on_space(void) { char *str = strdup("foo bar baz"); char *temp; if (!str) { CU_FAIL ("semanage_split_on_space: unable to perform test, no memory"); } temp = semanage_split_on_space(str); if (strncmp(temp, "bar", 3)) { CU_FAIL("semanage_split_on_space: token did not match"); } temp = semanage_split_on_space(temp); if (strncmp(temp, "baz", 3)) { CU_FAIL("semanage_split_on_space: token did not match"); } temp = semanage_split_on_space(temp); if (strcmp(temp, "")) { CU_FAIL("semanage_split_on_space: token did not match"); } free(str); } void test_semanage_split(void) { char *str = strdup("foo1 foo2 foo:bar"); char *temp; if (!str) { CU_FAIL ("semanage_split_on_space: unable to perform test, no memory"); return; } temp = semanage_split(str, NULL); CU_ASSERT_NSTRING_EQUAL(temp, "foo2", 4); temp = semanage_split(temp, ""); CU_ASSERT_NSTRING_EQUAL(temp, "foo", 3); temp = semanage_split(temp, ":"); CU_ASSERT_NSTRING_EQUAL(temp, "bar", 3); free(str); } void test_semanage_list(void) { semanage_list_t *list = NULL; semanage_list_t *ptr = NULL; char *temp = NULL; int retval = 0; CU_ASSERT_FALSE(semanage_list_push(&list, "foo")); CU_ASSERT_PTR_NOT_NULL(list); CU_ASSERT_FALSE(semanage_list_push(&list, "bar")); CU_ASSERT_FALSE(semanage_list_push(&list, "gonk")); CU_ASSERT_FALSE(semanage_list_push(&list, "zebra")); for (ptr = list; ptr; ptr = ptr->next) retval++; CU_ASSERT_EQUAL(retval, 4); temp = semanage_list_pop(&list); CU_ASSERT_STRING_EQUAL(temp, "zebra"); CU_ASSERT_FALSE(semanage_list_push(&list, temp)); free(temp); temp = NULL; retval = 0; for (ptr = list; ptr; ptr = ptr->next) retval++; CU_ASSERT_EQUAL(retval, 4); retval = semanage_list_sort(&list); if (retval) { CU_FAIL ("semanage_list_sort: error unrelated to sort (memory?)"); goto past_sort; } CU_ASSERT_STRING_EQUAL(list->data, "bar"); CU_ASSERT_STRING_EQUAL(list->next->data, "foo"); CU_ASSERT_STRING_EQUAL(list->next->next->data, "gonk"); CU_ASSERT_STRING_EQUAL(list->next->next->next->data, "zebra"); past_sort: ptr = semanage_list_find(list, "zebra"); CU_ASSERT_PTR_NOT_NULL(ptr); ptr = semanage_list_find(list, "bogus"); CU_ASSERT_PTR_NULL(ptr); semanage_list_destroy(&list); CU_ASSERT_PTR_NULL(list); } void test_semanage_str_count(void) { char *test_string = "abaababbaaaba"; CU_ASSERT_EQUAL(semanage_str_count(test_string, 'z'), 0); CU_ASSERT_EQUAL(semanage_str_count(test_string, 'a'), 8); CU_ASSERT_EQUAL(semanage_str_count(test_string, 'b'), 5); } void test_semanage_rtrim(void) { char *str = strdup("/blah/foo/bar/baz/"); CU_ASSERT_PTR_NOT_NULL_FATAL(str); semanage_rtrim(str, 'Q'); CU_ASSERT_STRING_EQUAL(str, "/blah/foo/bar/baz/"); semanage_rtrim(str, 'a'); CU_ASSERT_STRING_EQUAL(str, "/blah/foo/bar/b"); semanage_rtrim(str, '/'); CU_ASSERT_STRING_EQUAL(str, "/blah/foo/bar"); } void test_semanage_findval(void) { char *tok; if (!fptr) { CU_FAIL_FATAL("Temporary file was not created, aborting test."); } tok = semanage_findval(fname, "one", NULL); CU_ASSERT_STRING_EQUAL(tok, ""); rewind(fptr); tok = semanage_findval(fname, "one", ""); CU_ASSERT_STRING_EQUAL(tok, ""); free(tok); rewind(fptr); tok = semanage_findval(fname, "sigma", "="); CU_ASSERT_STRING_EQUAL(tok, "foo"); } int PREDICATE(const char *str) { return semanage_is_prefix(str, "#"); } void test_slurp_file_filter(void) { semanage_list_t *data, *tmp; int cnt = 0; if (!fptr) { CU_FAIL_FATAL("Temporary file was not created, aborting test."); } rewind(fptr); data = semanage_slurp_file_filter(fptr, PREDICATE); CU_ASSERT_PTR_NOT_NULL_FATAL(data); for (tmp = data; tmp; tmp = tmp->next) cnt++; CU_ASSERT_EQUAL(cnt, 2); semanage_list_destroy(&data); } libsemanage-2.3/tests/test_utilities.h000066400000000000000000000002401233221606300202040ustar00rootroot00000000000000#include int semanage_utilities_test_init(void); int semanage_utilities_test_cleanup(void); int semanage_utilities_add_tests(CU_pSuite suite); libsemanage-2.3/tests/utilities.c000066400000000000000000000022431233221606300171450ustar00rootroot00000000000000/* Authors: Christopher Ashworth * * Copyright (C) 2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* The purpose of this file is to provide some functions commonly needed * by our unit tests. */ #include "utilities.h" /* Silence any error output caused by our tests * by using this dummy function to catch messages. */ void test_msg_handler(void *varg, semanage_handle_t * handle, const char *fmt, ...) { } libsemanage-2.3/tests/utilities.h000066400000000000000000000017161233221606300171560ustar00rootroot00000000000000/* Authors: Christopher Ashworth * * Copyright (C) 2006 Tresys Technology, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "handle.h" void test_msg_handler(void *varg, semanage_handle_t * handle, const char *fmt, ...);