pax_global_header00006660000000000000000000000064147621173720014524gustar00rootroot0000000000000052 comment=8e9157bbeea1899b7b8b257e7eaa71efef3fffed libsemanage-3.8.1/000077500000000000000000000000001476211737200140045ustar00rootroot00000000000000libsemanage-3.8.1/.gitignore000066400000000000000000000000621476211737200157720ustar00rootroot00000000000000src/conf-parse.c src/conf-parse.h src/conf-scan.c libsemanage-3.8.1/LICENSE000066400000000000000000000634651476211737200150270ustar00rootroot00000000000000 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-3.8.1/Makefile000066400000000000000000000010041476211737200154370ustar00rootroot00000000000000all: $(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 $(MAKE) -C utils 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-3.8.1/VERSION000066400000000000000000000000061476211737200150500ustar00rootroot000000000000003.8.1 libsemanage-3.8.1/example/000077500000000000000000000000001476211737200154375ustar00rootroot00000000000000libsemanage-3.8.1/example/test_fcontext.c000066400000000000000000000034741476211737200205040ustar00rootroot00000000000000#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-3.8.1/include/000077500000000000000000000000001476211737200154275ustar00rootroot00000000000000libsemanage-3.8.1/include/Makefile000066400000000000000000000004401476211737200170650ustar00rootroot00000000000000# Installation directories. PREFIX ?= /usr INCDIR ?= $(PREFIX)/include/semanage all: install: all test -d $(DESTDIR)$(INCDIR) || install -m 755 -d $(DESTDIR)$(INCDIR) install -m 644 $(wildcard semanage/*.h) $(DESTDIR)$(INCDIR) indent: ../../scripts/Lindent $(wildcard semanage/*.h) libsemanage-3.8.1/include/semanage/000077500000000000000000000000001476211737200172075ustar00rootroot00000000000000libsemanage-3.8.1/include/semanage/boolean_record.h000066400000000000000000000031231476211737200223340ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/booleans_active.h000066400000000000000000000020031476211737200225100ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/booleans_local.h000066400000000000000000000021661476211737200223410ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/booleans_policy.h000066400000000000000000000014641476211737200225460ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/context_record.h000066400000000000000000000034071476211737200224060ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/debug.h000066400000000000000000000035331476211737200204520ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/fcontext_record.h000066400000000000000000000046431476211737200225570ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/fcontexts_local.h000066400000000000000000000022371476211737200225530ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/fcontexts_policy.h000066400000000000000000000017741476211737200227650ustar00rootroot00000000000000/* 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); extern int semanage_fcontext_list_homedirs(semanage_handle_t * handle, semanage_fcontext_t *** records, unsigned int *count); #endif libsemanage-3.8.1/include/semanage/handle.h000066400000000000000000000165301476211737200206200ustar00rootroot00000000000000/* 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_ #include /* 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. */ extern 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. */ extern 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. */ extern void semanage_select_store(semanage_handle_t * handle, const char *path, enum semanage_connect_type storetype); /* Just reload the policy */ extern 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 */ extern 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) */ extern void semanage_set_rebuild(semanage_handle_t * handle, int do_rebuild); /* set whether to rebuild the policy on commit when potential changes * to store files since last rebuild are detected, * 1 for yes (default), 0 for no */ extern void semanage_set_check_ext_changes(semanage_handle_t * handle, int do_check); /* Fills *compiler_path with the location of the hll compiler sh->conf->compiler_directory_path * corresponding to lang_ext. * Upon success returns 0, -1 on error. */ extern int semanage_get_hll_compiler_path(semanage_handle_t *sh, const char *lang_ext, char **compiler_path); /* 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) */ extern void semanage_set_create_store(semanage_handle_t * handle, int create_store); /*Get whether or not dontaudits will be disabled upon commit */ extern int semanage_get_disable_dontaudit(semanage_handle_t * handle); /* Set whether or not to disable dontaudits upon commit */ extern 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 */ extern void semanage_set_check_contexts(semanage_handle_t * sh, int do_check_contexts); /* Get the default priority. */ extern uint16_t semanage_get_default_priority(semanage_handle_t *sh); /* Set the default priority. */ extern int semanage_set_default_priority(semanage_handle_t *sh, uint16_t priority); /* 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. */ extern 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. */ extern 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. */ extern 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. */ extern 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. */ extern 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 occurred */ extern int semanage_access_check(semanage_handle_t * sh); /* returns 0 if not connected, 1 if connected */ extern int semanage_is_connected(semanage_handle_t * sh); /* returns 1 if policy is MLS, 0 otherwise. */ extern int semanage_mls_enabled(semanage_handle_t *sh); /* Change to alternate semanage root path */ extern int semanage_set_root(const char *path); /* Get the current semanage root path */ extern const char * semanage_root(void); /* Get whether or not needless unused branch of tunables would be preserved */ extern int semanage_get_preserve_tunables(semanage_handle_t * handle); /* Set whether or not to preserve the needless unused branch of tunables */ extern void semanage_set_preserve_tunables(semanage_handle_t * handle, int preserve_tunables); /* Get the flag value for whether or not caching is ignored for compiled CIL modules from HLL files */ extern int semanage_get_ignore_module_cache(semanage_handle_t *handle); /* Set semanage_handle flag for whether or not to ignore caching of compiled CIL modules from HLL files */ extern void semanage_set_ignore_module_cache(semanage_handle_t *handle, int ignore_module_cache); /* set the store root path for semanage output files */ extern void semanage_set_store_root(semanage_handle_t *sh, const char *store_root); /* 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-3.8.1/include/semanage/ibendport_record.h000066400000000000000000000041741476211737200227120ustar00rootroot00000000000000/*Copyright (C) 2005 Red Hat, Inc. */ #ifndef _SEMANAGE_IBENDPORT_RECORD_H_ #define _SEMANAGE_IBENDPORT_RECORD_H_ #include #include #include #ifndef _SEMANAGE_IBENDPORT_DEFINED_ struct semanage_ibendport; struct semanage_ibendport_key; typedef struct semanage_ibendport semanage_ibendport_t; typedef struct semanage_ibendport_key semanage_ibendport_key_t; #define _SEMANAGE_IBENDPORT_DEFINED_ #endif extern int semanage_ibendport_compare(const semanage_ibendport_t *ibendport, const semanage_ibendport_key_t *key); extern int semanage_ibendport_compare2(const semanage_ibendport_t *ibendport, const semanage_ibendport_t *ibendport2); extern int semanage_ibendport_key_create(semanage_handle_t *handle, const char *ibdev_name, int port, semanage_ibendport_key_t **key_ptr); extern int semanage_ibendport_key_extract(semanage_handle_t *handle, const semanage_ibendport_t *ibendport, semanage_ibendport_key_t **key_ptr); extern void semanage_ibendport_key_free(semanage_ibendport_key_t *key); extern int semanage_ibendport_get_ibdev_name(semanage_handle_t *handle, const semanage_ibendport_t *ibendport, char **ibdev_name_ptr); extern int semanage_ibendport_set_ibdev_name(semanage_handle_t *handle, semanage_ibendport_t *ibendport, const char *ibdev_name); extern int semanage_ibendport_get_port(const semanage_ibendport_t *ibendport); extern void semanage_ibendport_set_port(semanage_ibendport_t *ibendport, int port); extern semanage_context_t *semanage_ibendport_get_con(const semanage_ibendport_t *ibendport); extern int semanage_ibendport_set_con(semanage_handle_t *handle, semanage_ibendport_t *ibendport, semanage_context_t *con); extern int semanage_ibendport_create(semanage_handle_t *handle, semanage_ibendport_t **ibendport_ptr); extern int semanage_ibendport_clone(semanage_handle_t *handle, const semanage_ibendport_t *ibendport, semanage_ibendport_t **ibendport_ptr); extern void semanage_ibendport_free(semanage_ibendport_t *ibendport); #endif libsemanage-3.8.1/include/semanage/ibendports_local.h000066400000000000000000000022501476211737200227020ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Technologies Inc */ #ifndef _SEMANAGE_IBENDPORTS_LOCAL_H_ #define _SEMANAGE_IBENDPORTS_LOCAL_H_ #include #include extern int semanage_ibendport_modify_local(semanage_handle_t *handle, const semanage_ibendport_key_t *key, const semanage_ibendport_t *data); extern int semanage_ibendport_del_local(semanage_handle_t *handle, const semanage_ibendport_key_t *key); extern int semanage_ibendport_query_local(semanage_handle_t *handle, const semanage_ibendport_key_t *key, semanage_ibendport_t **response); extern int semanage_ibendport_exists_local(semanage_handle_t *handle, const semanage_ibendport_key_t *key, int *response); extern int semanage_ibendport_count_local(semanage_handle_t *handle, unsigned int *response); extern int semanage_ibendport_iterate_local(semanage_handle_t *handle, int (*handler)(const semanage_ibendport_t *record, void *varg), void *handler_arg); extern int semanage_ibendport_list_local(semanage_handle_t *handle, semanage_ibendport_t ***records, unsigned int *count); #endif libsemanage-3.8.1/include/semanage/ibendports_policy.h000066400000000000000000000016001476211737200231050ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Techonologies Inc */ #ifndef _SEMANAGE_IBENDPORTS_POLICY_H_ #define _SEMANAGE_IBENDPORTS_POLICY_H_ #include #include extern int semanage_ibendport_query(semanage_handle_t *handle, const semanage_ibendport_key_t *key, semanage_ibendport_t **response); extern int semanage_ibendport_exists(semanage_handle_t *handle, const semanage_ibendport_key_t *key, int *response); extern int semanage_ibendport_count(semanage_handle_t *handle, unsigned int *response); extern int semanage_ibendport_iterate(semanage_handle_t *handle, int (*handler)(const semanage_ibendport_t *record, void *varg), void *handler_arg); extern int semanage_ibendport_list(semanage_handle_t *handle, semanage_ibendport_t ***records, unsigned int *count); #endif libsemanage-3.8.1/include/semanage/ibpkey_record.h000066400000000000000000000045721476211737200222110ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Technologies Inc */ #ifndef _SEMANAGE_IBPKEY_RECORD_H_ #define _SEMANAGE_IBPKEY_RECORD_H_ #include #include #include #include #ifndef _SEMANAGE_IBPKEY_DEFINED_ struct semanage_ibpkey; struct semanage_ibpkey_key; typedef struct semanage_ibpkey semanage_ibpkey_t; typedef struct semanage_ibpkey_key semanage_ibpkey_key_t; #define _SEMANAGE_IBPKEY_DEFINED_ #endif extern int semanage_ibpkey_compare(const semanage_ibpkey_t *ibpkey, const semanage_ibpkey_key_t *key); extern int semanage_ibpkey_compare2(const semanage_ibpkey_t *ibpkey, const semanage_ibpkey_t *ibpkey2); extern int semanage_ibpkey_key_create(semanage_handle_t *handle, const char *subnet_prefix, int low, int high, semanage_ibpkey_key_t **key_ptr); extern int semanage_ibpkey_key_extract(semanage_handle_t *handle, const semanage_ibpkey_t *ibpkey, semanage_ibpkey_key_t **key_ptr); extern void semanage_ibpkey_key_free(semanage_ibpkey_key_t *key); extern int semanage_ibpkey_get_subnet_prefix(semanage_handle_t *handle, const semanage_ibpkey_t *ibpkey, char **subnet_prefix_ptr); extern uint64_t semanage_ibpkey_get_subnet_prefix_bytes(const semanage_ibpkey_t *ibpkey); extern int semanage_ibpkey_set_subnet_prefix(semanage_handle_t *handle, semanage_ibpkey_t *ibpkey, const char *subnet_prefix); extern void semanage_ibpkey_set_subnet_prefix_bytes(semanage_ibpkey_t *ibpkey, uint64_t subnet_prefix); extern int semanage_ibpkey_get_low(const semanage_ibpkey_t *ibpkey); extern int semanage_ibpkey_get_high(const semanage_ibpkey_t *ibpkey); extern void semanage_ibpkey_set_pkey(semanage_ibpkey_t *ibpkey, int pkey_num); extern void semanage_ibpkey_set_range(semanage_ibpkey_t *ibpkey, int low, int high); extern semanage_context_t *semanage_ibpkey_get_con(const semanage_ibpkey_t *ibpkey); extern int semanage_ibpkey_set_con(semanage_handle_t *handle, semanage_ibpkey_t *ibpkey, semanage_context_t *con); extern int semanage_ibpkey_create(semanage_handle_t *handle, semanage_ibpkey_t **ibpkey_ptr); extern int semanage_ibpkey_clone(semanage_handle_t *handle, const semanage_ibpkey_t *ibpkey, semanage_ibpkey_t **ibpkey_ptr); extern void semanage_ibpkey_free(semanage_ibpkey_t *ibpkey); #endif libsemanage-3.8.1/include/semanage/ibpkeys_local.h000066400000000000000000000021661476211737200222050ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Technologies Inc */ #ifndef _SEMANAGE_IBPKEYS_LOCAL_H_ #define _SEMANAGE_IBPKEYS_LOCAL_H_ #include #include extern int semanage_ibpkey_modify_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, const semanage_ibpkey_t *data); extern int semanage_ibpkey_del_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key); extern int semanage_ibpkey_query_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, semanage_ibpkey_t **response); extern int semanage_ibpkey_exists_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, int *response); extern int semanage_ibpkey_count_local(semanage_handle_t *handle, unsigned int *response); extern int semanage_ibpkey_iterate_local(semanage_handle_t *handle, int (*handler)(const semanage_ibpkey_t * record, void *varg), void *handler_arg); extern int semanage_ibpkey_list_local(semanage_handle_t *handle, semanage_ibpkey_t ***records, unsigned int *count); #endif libsemanage-3.8.1/include/semanage/ibpkeys_policy.h000066400000000000000000000014751476211737200224140ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Technolgies Inc. */ #ifndef _SEMANAGE_IBPKEYS_POLICY_H_ #define _SEMANAGE_IBPKEYS_POLICY_H_ #include #include extern int semanage_ibpkey_query(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, semanage_ibpkey_t **response); extern int semanage_ibpkey_exists(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, int *response); extern int semanage_ibpkey_count(semanage_handle_t *handle, unsigned int *response); extern int semanage_ibpkey_iterate(semanage_handle_t *handle, int (*handler)(const semanage_ibpkey_t *record, void *varg), void *handler_arg); extern int semanage_ibpkey_list(semanage_handle_t *handle, semanage_ibpkey_t ***records, unsigned int *count); #endif libsemanage-3.8.1/include/semanage/iface_record.h000066400000000000000000000037131476211737200217710ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/interfaces_local.h000066400000000000000000000021771476211737200226640ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/interfaces_policy.h000066400000000000000000000015021476211737200230600ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/modules.h000066400000000000000000000235441476211737200210400ustar00rootroot00000000000000/* 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 #include #include typedef struct semanage_module_key semanage_module_key_t; /* High level module management functions. These are all part of * a transaction */ extern int semanage_module_install(semanage_handle_t *, char *module_data, size_t data_len, const char *name, const char *ext_lang); extern int semanage_module_install_file(semanage_handle_t *, const char *module_name); extern int semanage_module_remove(semanage_handle_t *, char *module_name); /* semanage_module_info is for getting information on installed modules, only name at this time */ typedef struct semanage_module_info semanage_module_info_t; /* Look up a module using @modkey. The module's raw data is returned as a * @mapped_data blob and size of the mapped_data is returned as @data_len. * @modinfo contains additional information which can be used by the caller such * as the high level language extension of @mapped_data. * * On success, the caller is responsible for unmapping @mapped_data with munmap(), * destroying @modinfo with semanage_module_info_destroy(), and freeing @modinfo. * * Returns 0 on success and -1 on error. */ extern int semanage_module_extract(semanage_handle_t *sh, semanage_module_key_t *modkey, int extract_cil, void **mapped_data, size_t *data_len, semanage_module_info_t **modinfo); extern int semanage_module_list(semanage_handle_t *, semanage_module_info_t **, int *num_modules); extern void semanage_module_info_datum_destroy(semanage_module_info_t *); extern semanage_module_info_t *semanage_module_list_nth(semanage_module_info_t * list, int n); extern const char *semanage_module_get_name(semanage_module_info_t *); /* Module Info */ /* Creates a module info struct. * * Returns 0 on success and -1 on failure. * * The @modinfo should be destroyed with semanage_module_info_destroy. * The caller should call free() on the struct. */ extern int semanage_module_info_create(semanage_handle_t *sh, semanage_module_info_t **modinfo); /* Frees the members of the module info struct. * * Returns 0 on success and -1 on failure. * * The caller should call free() on the struct. */ extern int semanage_module_info_destroy(semanage_handle_t *handle, semanage_module_info_t *modinfo); /* Module Info Getters */ /* Get @priority from @modinfo. * * Returns 0 on success and -1 on error. */ extern int semanage_module_info_get_priority(semanage_handle_t *sh, semanage_module_info_t *modinfo, uint16_t *priority); /* Get @name from @modinfo. Caller should not free @name. * * Returns 0 on success and -1 on error. */ extern int semanage_module_info_get_name(semanage_handle_t *sh, semanage_module_info_t *modinfo, const char **name); /* Get @lang_ext from @modinfo. Caller should not free @lang_ext. * * Returns 0 on success and -1 on error. */ extern int semanage_module_info_get_lang_ext(semanage_handle_t *sh, semanage_module_info_t *modinfo, const char **lang_ext); /* Get @enabled from @modinfo. * * Returns 0 on success and -1 on error. */ extern int semanage_module_info_get_enabled(semanage_handle_t *sh, semanage_module_info_t *modinfo, int *enabled); /* Module Info Setters */ /* Set @priority in @modinfo. * * Returns 0 on success and -1 on error. */ extern int semanage_module_info_set_priority(semanage_handle_t *sh, semanage_module_info_t *modinfo, uint16_t priority); /* Set @name in @modinfo. * * Returns 0 on success and -1 on error. */ extern int semanage_module_info_set_name(semanage_handle_t *sh, semanage_module_info_t *modinfo, const char *name); /* Set @lang_ext in @modinfo. * * Returns 0 on success and -1 on error. */ extern int semanage_module_info_set_lang_ext(semanage_handle_t *sh, semanage_module_info_t *modinfo, const char *lang_ext); /* Set @enabled in @modinfo. * * Returns 0 on success and -1 on error. */ extern int semanage_module_info_set_enabled(semanage_handle_t *sh, semanage_module_info_t *modinfo, int enabled); /* Module Key */ /* Creates a module key struct. * * Return 0 on success, and -1 on error. * * The @modkey should be destroyed with semanage_module_key_destroy. * The caller should call free() on the struct. */ extern int semanage_module_key_create(semanage_handle_t *sh, semanage_module_key_t **modkey); /* Frees members of the @modkey, but not the struct. The caller should * call free() on struct. * * Returns 0 on success, and -1 on error. */ extern int semanage_module_key_destroy(semanage_handle_t *sh, semanage_module_key_t *modkey); /* Module Key Getters */ /* Get @name from @modkey. Caller should not free @name. * * Returns 0 on success and -1 on error. */ extern int semanage_module_key_get_name(semanage_handle_t *sh, semanage_module_key_t *modkey, const char **name); /* Get @name from @modkey. * * Returns 0 on success and -1 on error. */ extern int semanage_module_key_get_priority(semanage_handle_t *sh, semanage_module_key_t *modkey, uint16_t *priority); /* Module Key Setters */ /* Set @name in @modkey. * * Returns 0 on success and -1 on error. */ extern int semanage_module_key_set_name(semanage_handle_t *sh, semanage_module_key_t *modkey, const char *name); /* Set @priority in @modkey. * * Returns 0 on success and -1 on error. */ extern int semanage_module_key_set_priority(semanage_handle_t *sh, semanage_module_key_t *modkey, uint16_t priority); /* Set module @enabled status from @modkey. Modules are enabled on a per * module name basis (across all priorities). @modkey only needs to have * name set (priority is ignored). * * Returns 0 on success and -1 on error. */ extern int semanage_module_set_enabled(semanage_handle_t *sh, const semanage_module_key_t *modkey, int enabled); /* Lookup @modinfo by @modkey. Caller should use * semanage_module_info_destroy and free on @modinfo. * * Returns 0 on success and -1 on error. */ extern int semanage_module_get_module_info(semanage_handle_t *sh, const semanage_module_key_t *modkey, semanage_module_info_t **modinfo); /* Create a list of all modules in @modinfos of length @modinfos_len. * The list will be sorted from high priority to low and alphabetically * by module name within a priority. * * Caller should use semanage_module_info_destroy on each modinfo in * @modinfos and free on @modinfos. * * Returns 0 on success and -1 on error. */ extern int semanage_module_list_all(semanage_handle_t *sh, semanage_module_info_t **modinfos, int *modinfos_len); /* Install the module indicated by @modinfo with input data from * @module_data with length @data_len. * * @modinfo must have all values filled in. * @module_data may be bzip compressed. * * Returns: * 0 success * -1 failure, out of memory * -2 failure, invalid @modinfo * -3 failure, error writing file */ extern int semanage_module_install_info(semanage_handle_t *sh, const semanage_module_info_t *modinfo, char *data, size_t data_len); /* Remove the module indicated by @modkey. * @modkey must have key values filled in. * * Returns: * 0 success * -1 failure, out of memory * -2 failure, @module not found or couldn't be removed */ extern int semanage_module_remove_key(semanage_handle_t *sh, const semanage_module_key_t *modkey); /* Module Enabled */ /* Get module @enabled status from @modkey. Modules are enabled on a per * module name basis (across all priorities). @modkey only needs to have * name set (priority is ignored). * * Returns 0 on success and -1 on error. */ extern int semanage_module_get_enabled(semanage_handle_t *sh, const semanage_module_key_t *modkey, int *enabled); /* Compute checksum for @modkey module contents. * * If @checksum is NULL, the function will just return the length of the * checksum string in @checksum_len (checksum strings are guaranteed to * have a fixed length for a given libsemanage binary). @modkey and @cil * are ignored in this case and should be set to NULL and 0 (respectively). * * If @checksum is non-NULL, on success, @checksum will point to a buffer * containing the checksum string and @checksum_len will point to the * length of the string (without the null terminator). The semantics of * @cil are the same as for @extract_cil in semanage_module_extract(). * * The caller is responsible to free the buffer returned in @checksum (using * free(3)). * * Callers may assume that if the checksum strings for two modules match, * the module content is the same (collisions are theoretically possible, * yet extremely unlikely). * * Returns 0 on success and -1 on error. */ extern int semanage_module_compute_checksum(semanage_handle_t *sh, semanage_module_key_t *modkey, int cil, char **checksum, size_t *checksum_len); #endif libsemanage-3.8.1/include/semanage/node_record.h000066400000000000000000000055221476211737200216470ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/nodes_local.h000066400000000000000000000021551476211737200216450ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/nodes_policy.h000066400000000000000000000014531476211737200220520ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/port_record.h000066400000000000000000000041351476211737200217050ustar00rootroot00000000000000/* 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 #define SEMANAGE_PROTO_DCCP 2 #define SEMANAGE_PROTO_SCTP 3 /* 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-3.8.1/include/semanage/ports_local.h000066400000000000000000000021551476211737200217040ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/ports_policy.h000066400000000000000000000014531476211737200221110ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/semanage.h000066400000000000000000000041321476211737200211400ustar00rootroot00000000000000/* 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 #include #include /* Dbase */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif libsemanage-3.8.1/include/semanage/seuser_record.h000066400000000000000000000036051476211737200222300ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/seusers_local.h000066400000000000000000000021721476211737200222250ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/seusers_policy.h000066400000000000000000000015031476211737200224270ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/user_record.h000066400000000000000000000053671476211737200217070ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/users_local.h000066400000000000000000000021551476211737200216760ustar00rootroot00000000000000/* 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-3.8.1/include/semanage/users_policy.h000066400000000000000000000014531476211737200221030ustar00rootroot00000000000000/* 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-3.8.1/man/000077500000000000000000000000001476211737200145575ustar00rootroot00000000000000libsemanage-3.8.1/man/Makefile000066400000000000000000000014101476211737200162130ustar00rootroot00000000000000# Installation directories. LINGUAS ?= PREFIX ?= /usr MANDIR ?= $(PREFIX)/share/man MAN3SUBDIR ?= man3 MAN5SUBDIR ?= man5 MAN3DIR ?= $(MANDIR)/$(MAN3SUBDIR) MAN5DIR ?= $(MANDIR)/$(MAN5SUBDIR) all: install: all mkdir -p $(DESTDIR)$(MAN3DIR) mkdir -p $(DESTDIR)$(MAN5DIR) install -m 644 man3/*.3 $(DESTDIR)$(MAN3DIR) install -m 644 man5/*.5 $(DESTDIR)$(MAN5DIR) for lang in $(LINGUAS) ; do \ if [ -e $${lang}/man3 ] ; then \ mkdir -p $(DESTDIR)$(MANDIR)/$${lang}/$(MAN3SUBDIR) ; \ install -m 644 $${lang}/man3/*.3 $(DESTDIR)$(MANDIR)/$${lang}/$(MAN3SUBDIR) ; \ fi ; \ if [ -e $${lang}/man5 ] ; then \ mkdir -p $(DESTDIR)$(MANDIR)/$${lang}/$(MAN5SUBDIR) ; \ install -m 644 $${lang}/man5/*.5 $(DESTDIR)$(MANDIR)/$${lang}/$(MAN5SUBDIR) ; \ fi ; \ done libsemanage-3.8.1/man/man3/000077500000000000000000000000001476211737200154155ustar00rootroot00000000000000libsemanage-3.8.1/man/man3/semanage_bool.3000066400000000000000000000064421476211737200203020ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_bool_count.3000066400000000000000000000000321476211737200214770ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_bool_count_active.3000066400000000000000000000000321476211737200230320ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_bool_count_local.3000066400000000000000000000000321476211737200226510ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_bool_del_local.3000066400000000000000000000000301476211737200222630ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-3.8.1/man/man3/semanage_bool_exists.3000066400000000000000000000000331476211737200216670ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_bool_exists_active.3000066400000000000000000000000331476211737200232220ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_bool_exists_local.3000066400000000000000000000000331476211737200230410ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_bool_iterate.3000066400000000000000000000000341476211737200220060ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_bool_iterate_active.3000066400000000000000000000000341476211737200233410ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_bool_iterate_local.3000066400000000000000000000000341476211737200231600ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_bool_list.3000066400000000000000000000000311476211737200213210ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_bool_list_active.3000066400000000000000000000000311476211737200226540ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_bool_list_local.3000066400000000000000000000000311476211737200224730ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_bool_modify_local.3000066400000000000000000000000331476211737200230110ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-3.8.1/man/man3/semanage_bool_query.3000066400000000000000000000000321476211737200215140ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_bool_query_active.3000066400000000000000000000000321476211737200230470ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_bool_query_local.3000066400000000000000000000000321476211737200226660ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_bool_set_active.3000066400000000000000000000030571476211737200225070ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_count.3000066400000000000000000000022401476211737200204670ustar00rootroot00000000000000.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 pointed 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-3.8.1/man/man3/semanage_del.3000066400000000000000000000027571476211737200201200ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_exists.3000066400000000000000000000025471476211737200206700ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_fcontext.3000066400000000000000000000064551476211737200212050ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_fcontext_count.3000066400000000000000000000000321476211737200223760ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_fcontext_count_local.3000066400000000000000000000000321476211737200235500ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_fcontext_del_local.3000066400000000000000000000000301476211737200231620ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-3.8.1/man/man3/semanage_fcontext_exists.3000066400000000000000000000000331476211737200225660ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_fcontext_exists_local.3000066400000000000000000000000331476211737200237400ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_fcontext_iterate.3000066400000000000000000000000341476211737200227050ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_fcontext_iterate_local.3000066400000000000000000000000341476211737200240570ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_fcontext_list.3000066400000000000000000000000311476211737200222200ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_fcontext_list_local.3000066400000000000000000000000311476211737200233720ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_fcontext_modify_local.3000066400000000000000000000000331476211737200237100ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-3.8.1/man/man3/semanage_fcontext_query.3000066400000000000000000000000321476211737200224130ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_fcontext_query_local.3000066400000000000000000000000321476211737200235650ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_iface.3000066400000000000000000000057311476211737200204160ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_iface_count.3000066400000000000000000000000321476211737200216130ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_iface_count_local.3000066400000000000000000000000321476211737200227650ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_iface_del_local.3000066400000000000000000000000301476211737200223770ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-3.8.1/man/man3/semanage_iface_exists.3000066400000000000000000000000331476211737200220030ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_iface_exists_local.3000066400000000000000000000000331476211737200231550ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_iface_iterate.3000066400000000000000000000000341476211737200221220ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_iface_iterate_local.3000066400000000000000000000000341476211737200232740ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_iface_list.3000066400000000000000000000000311476211737200214350ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_iface_list_local.3000066400000000000000000000000311476211737200226070ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_iface_modify_local.3000066400000000000000000000000331476211737200231250ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-3.8.1/man/man3/semanage_iface_query.3000066400000000000000000000000321476211737200216300ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_iface_query_local.3000066400000000000000000000000321476211737200230020ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_iterate.3000066400000000000000000000041321476211737200207760ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_list.3000066400000000000000000000026761476211737200203270ustar00rootroot00000000000000.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 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-3.8.1/man/man3/semanage_modify.3000066400000000000000000000033341476211737200206330ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_node.3000066400000000000000000000073031476211737200202710ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_node_count.3000066400000000000000000000000321476211737200214710ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_node_count_local.3000066400000000000000000000000321476211737200226430ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_node_del_local.3000066400000000000000000000000301476211737200222550ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-3.8.1/man/man3/semanage_node_exists.3000066400000000000000000000000331476211737200216610ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_node_exists_local.3000066400000000000000000000000331476211737200230330ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_node_iterate.3000066400000000000000000000000341476211737200220000ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_node_iterate_local.3000066400000000000000000000000341476211737200231520ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_node_list.3000066400000000000000000000000311476211737200213130ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_node_list_local.3000066400000000000000000000000311476211737200224650ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_node_modify_local.3000066400000000000000000000000331476211737200230030ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-3.8.1/man/man3/semanage_node_query.3000066400000000000000000000000321476211737200215060ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_node_query_local.3000066400000000000000000000000321476211737200226600ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_port.3000066400000000000000000000062601476211737200203310ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_port_count.3000066400000000000000000000000321476211737200215300ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_port_count_local.3000066400000000000000000000000321476211737200227020ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_port_del_local.3000066400000000000000000000000301476211737200223140ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-3.8.1/man/man3/semanage_port_exists.3000066400000000000000000000000331476211737200217200ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_port_exists_local.3000066400000000000000000000000331476211737200230720ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_port_iterate.3000066400000000000000000000000341476211737200220370ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_port_iterate_local.3000066400000000000000000000000341476211737200232110ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_port_list.3000066400000000000000000000000311476211737200213520ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_port_list_local.3000066400000000000000000000000311476211737200225240ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_port_modify_local.3000066400000000000000000000000331476211737200230420ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-3.8.1/man/man3/semanage_port_query.3000066400000000000000000000000321476211737200215450ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_port_query_local.3000066400000000000000000000000321476211737200227170ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_query.3000066400000000000000000000027121476211737200205100ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_set_root.3000066400000000000000000000015061476211737200212010ustar00rootroot00000000000000.TH semanage_set_root 3 "1 June 2011" "dwalsh@redhat.com" "Libsemanage API documentation" .SH "NAME" semanage_set_root, semanage_root \- SELinux Management API .SH "SYNOPSIS" Set/get the alternate root directory for SELinux configuration directory. .B #include .B extern int semanage_set_root(const char *path); .B extern const char *semanage_root(void); .SH "DESCRIPTION" .TP The function semanage_set_root() sets an alternate root directory for SELinux configuration paths to be used by the semanage library. .SH "RETURN VALUE" The function semanage_set_root() returns \-1 in case of failure. Otherwise, 0 is returned. The function semanage_root() returns the semanage root. The returned value should not be modified by the caller. .SH "SEE ALSO" .BR semanage_handle_create "(3), " semanage_connect "(3), " libsemanage-3.8.1/man/man3/semanage_seuser.3000066400000000000000000000060341476211737200206520ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_seuser_count.3000066400000000000000000000000321476211737200220520ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_seuser_count_local.3000066400000000000000000000000321476211737200232240ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_seuser_del_local.3000066400000000000000000000000301476211737200226360ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-3.8.1/man/man3/semanage_seuser_exists.3000066400000000000000000000000331476211737200222420ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_seuser_exists_local.3000066400000000000000000000000331476211737200234140ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_seuser_iterate.3000066400000000000000000000000341476211737200223610ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_seuser_iterate_local.3000066400000000000000000000000341476211737200235330ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_seuser_list.3000066400000000000000000000000311476211737200216740ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_seuser_list_local.3000066400000000000000000000000311476211737200230460ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_seuser_modify_local.3000066400000000000000000000000331476211737200233640ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-3.8.1/man/man3/semanage_seuser_query.3000066400000000000000000000000321476211737200220670ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_seuser_query_local.3000066400000000000000000000000321476211737200232410ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_user.3000066400000000000000000000072251476211737200203250ustar00rootroot00000000000000.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-3.8.1/man/man3/semanage_user_count.3000066400000000000000000000000321476211737200215220ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_user_count_local.3000066400000000000000000000000321476211737200226740ustar00rootroot00000000000000.so man3/semanage_count.3 libsemanage-3.8.1/man/man3/semanage_user_del_local.3000066400000000000000000000000301476211737200223060ustar00rootroot00000000000000.so man3/semanage_del.3 libsemanage-3.8.1/man/man3/semanage_user_exists.3000066400000000000000000000000331476211737200217120ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_user_exists_local.3000066400000000000000000000000331476211737200230640ustar00rootroot00000000000000.so man3/semanage_exists.3 libsemanage-3.8.1/man/man3/semanage_user_iterate.3000066400000000000000000000000341476211737200220310ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_user_iterate_local.3000066400000000000000000000000341476211737200232030ustar00rootroot00000000000000.so man3/semanage_iterate.3 libsemanage-3.8.1/man/man3/semanage_user_list.3000066400000000000000000000000311476211737200213440ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_user_list_local.3000066400000000000000000000000311476211737200225160ustar00rootroot00000000000000.so man3/semanage_list.3 libsemanage-3.8.1/man/man3/semanage_user_modify_local.3000066400000000000000000000000331476211737200230340ustar00rootroot00000000000000.so man3/semanage_modify.3 libsemanage-3.8.1/man/man3/semanage_user_query.3000066400000000000000000000000321476211737200215370ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man3/semanage_user_query_local.3000066400000000000000000000000321476211737200227110ustar00rootroot00000000000000.so man3/semanage_query.3 libsemanage-3.8.1/man/man5/000077500000000000000000000000001476211737200154175ustar00rootroot00000000000000libsemanage-3.8.1/man/man5/semanage.conf.5000066400000000000000000000161111476211737200202110ustar00rootroot00000000000000.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 "example.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 root Specify an alternative root path to use for the store. The default is "/" .TP .B store-root Specify an alternative store_root path to use. The default is "/var/lib/selinux" .TP .B compiler-directory Specify an alternative directory that contains HLL to CIL compilers. The default value is "/usr/libexec/selinux/hll". .TP .B ignore-module-cache Whether or not to ignore the cache of CIL modules compiled from HLL. It can be set to either "true" or "false" and is set to "false" by default. If the cache is ignored, then all CIL modules are recompiled from their HLL modules. .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 target-platform The target platform to generate policies for. Valid values are "selinux" and "xen", and is set to "selinux" by default. .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 overrides 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". By default the setting from the policy is taken. .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". .TP .B remove-hll When set to "true", HLL files will be removed after compilation into CIL. In order to delete HLL files already compiled into CIL, modules will need to be recompiled with the .BR ignore-module-cache option set to 'true' or using the .BR ignore-module-cache option with semodule. The remove-hll option can be set to either "true" or "false" and by default it is set to "false". Please note that since this option deletes all HLL files, an updated HLL compiler will not be able to recompile the original HLL file into CIL. In order to compile the original HLL file into CIL, the same HLL file will need to be reinstalled. .TP .B optimize-policy When set to "true", the kernel policy will be optimized upon rebuilds. It can be set to either "true" or "false" and by default it is set to "true". .TP .B multiple-decls When set to "true", duplicate type, type attribute, and role declarations will be allowed. It can be set to either "true" or "false" and by default it is set to "true". .RE .PP For certain tasks the SELinux Management library resorts to running external commands. For the following commands their path and arguments can be overridden: .RS .RS .TP .B load_policy Command to load a kernel policy. Requires no argument. Defaults to .IR /sbin/load_policy with no arguments. .TP .B setfiles Command to verify file context definitions. Requires two arguments, the path to the kernel policy and the path to the file context definition file. Defaults to .IR /sbin/setfiles with the arguments '\-q \-c $@ $<'. .TP .B sefcontext_compile Command to compile a file context definition file. Requires one argument, the path to the to be compiled file context definition file. Defaults to .IR /sbin/sefcontext_compile with the argument '$@'. .RE .PP Either .IR path or .IR args can be omitted. The argument string must contain '$@' for the first required argument, and '$<' for the second one. The syntax for overriding an external command property is: .RS [\fIname\fR] .sp 0 path = /path/to/command .sp 0 args = --flag .sp 0 [end] .RE .TP Example .RS [sefcontext_compile] .sp 0 path = /usr/sbin/sefcontext_compile .sp 0 args = -r $@ .sp 0 [end] .RE .PP Optionally the SELinux Management library can invoke external commands to verify source modules (\fBverify module\fR), linked modules (\fBverify linked\fR), and kernel policies (\fBverify kernel\fR). The syntax is identical to the above command overrides. The program should exit with a value of 0 on success, and non zero on failure. .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-3.8.1/src/000077500000000000000000000000001476211737200145735ustar00rootroot00000000000000libsemanage-3.8.1/src/.gitignore000066400000000000000000000000711476211737200165610ustar00rootroot00000000000000semanageswig_wrap.c semanage.py semanageswig_ruby_wrap.c libsemanage-3.8.1/src/Makefile000066400000000000000000000133621476211737200162400ustar00rootroot00000000000000# 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 ?= python3 PYPREFIX ?= $(shell $(PYTHON) -c 'import sys;print("python-%d.%d" % sys.version_info[:2])') RUBY ?= ruby RUBYPREFIX ?= $(notdir $(RUBY)) PKG_CONFIG ?= pkg-config # Installation directories. PREFIX ?= /usr LIBDIR ?= $(PREFIX)/lib INCLUDEDIR ?= $(PREFIX)/include SYSCONFDIR ?= /etc PYINC ?= $(shell $(PKG_CONFIG) --cflags $(PYPREFIX)) PYLIBS ?= $(shell $(PKG_CONFIG) --libs $(PYPREFIX)) PYTHONLIBDIR ?= $(shell $(PYTHON) -c "import sysconfig; print(sysconfig.get_path('platlib', vars={'platbase': '$(PREFIX)', 'base': '$(PREFIX)'}))") PYCEXT ?= $(shell $(PYTHON) -c 'import importlib.machinery;print(importlib.machinery.EXTENSION_SUFFIXES[0])') RUBYINC ?= $(shell $(RUBY) -e 'puts "-I" + RbConfig::CONFIG["rubyarchhdrdir"] + " -I" + RbConfig::CONFIG["rubyhdrdir"]') RUBYLIBS ?= $(shell $(RUBY) -e 'puts "-L" + RbConfig::CONFIG["libdir"] + " -L" + RbConfig::CONFIG["archlibdir"] + " " + RbConfig::CONFIG["LIBRUBYARG_SHARED"]') RUBYINSTALL ?= $(shell $(RUBY) -e 'puts RbConfig::CONFIG["vendorarchdir"]') DEFAULT_SEMANAGE_CONF_LOCATION=$(SYSCONFDIR)/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 = 2 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 $(sort $(wildcard conf-*.[ch])) SRCS= $(filter-out $(GENERATED),$(sort $(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 \ -fno-semantic-interposition SWIG_CFLAGS += -Wno-error -Wno-unused-but-set-variable -Wno-unused-variable -Wno-shadow \ -Wno-unused-parameter -Wno-missing-prototypes override CFLAGS += -I../include -D_GNU_SOURCE RANLIB ?= ranlib SWIG = swig -Wall -python -o $(SWIGCOUT) -outdir ./ SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./ all: $(LIBA) $(LIBSO) $(LIBPC) pywrap: all $(SWIGSO) rubywrap: all $(SWIGRUBYSO) $(SWIGLOBJ): $(SWIGCOUT) $(CC) $(CPPFLAGS) $(CFLAGS) $(SWIG_CFLAGS) $(PYINC) -fPIC -DSHARED -c -o $@ $< $(SWIGRUBYLOBJ): $(SWIGRUBYCOUT) $(CC) $(CPPFLAGS) $(CFLAGS) $(SWIG_CFLAGS) $(RUBYINC) -fPIC -DSHARED -c -o $@ $< $(SWIGSO): $(SWIGLOBJ) $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -L. -shared -o $@ $< -lsemanage $(PYLIBS) $(SWIGRUBYSO): $(SWIGRUBYLOBJ) $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -L. -shared -o $@ $^ -lsemanage $(RUBYLIBS) $(LIBA): $(OBJS) $(AR) rcs $@ $^ $(RANLIB) $@ $(LIBSO): $(LOBJS) $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -lsepol -laudit -lselinux -lbz2 -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@:$(LIBDIR):; s:@includedir@:$(INCLUDEDIR):' < $< > $@ semanageswig_python_exception.i: exception.sh $(wildcard ../include/semanage/*.h) bash -e exception.sh > $@ || (rm -f $@ ; false) conf-scan.c: conf-scan.l conf-parse.h $(LEX) $(LFLAGS) -o $@ $< conf-parse.c: conf-parse.y $(YACC) $(YFLAGS) -o $@ $< conf-parse.h: conf-parse.c %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< %.lo: %.c $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -DSHARED -c -o $@ $< conf-parse.o: conf-parse.c $(CC) $(filter-out -Werror, $(CPPFLAGS) $(CFLAGS)) -c -o $@ $< conf-parse.lo: conf-parse.c $(CC) $(filter-out -Werror, $(CPPFLAGS) $(CFLAGS)) -fPIC -DSHARED -c -o $@ $< conf-scan.o: conf-scan.c $(CC) $(filter-out -Werror, $(CPPFLAGS) $(CFLAGS)) -c -o $@ $< conf-scan.lo: conf-scan.c $(CC) $(filter-out -Werror, $(CPPFLAGS) $(CFLAGS)) -fPIC -DSHARED -c -o $@ $< $(SWIGCOUT): $(SWIGIF) $(SWIG) $< $(SWIGRUBYCOUT): $(SWIGRUBYIF) $(SWIGRUBY) $< swigify: $(SWIGIF) $(SWIG) $< install: all test -d $(DESTDIR)$(LIBDIR) || install -m 755 -d $(DESTDIR)$(LIBDIR) install -m 644 $(LIBA) $(DESTDIR)$(LIBDIR) install -m 755 $(LIBSO) $(DESTDIR)$(LIBDIR) test -d $(DESTDIR)$(LIBDIR)/pkgconfig || install -m 755 -d $(DESTDIR)$(LIBDIR)/pkgconfig install -m 644 $(LIBPC) $(DESTDIR)$(LIBDIR)/pkgconfig test -f $(DESTDIR)$(DEFAULT_SEMANAGE_CONF_LOCATION) || install -m 644 -D semanage.conf $(DESTDIR)$(DEFAULT_SEMANAGE_CONF_LOCATION) cd $(DESTDIR)$(LIBDIR) && ln -sf $(LIBSO) $(TARGET) install-pywrap: pywrap test -d $(DESTDIR)$(PYTHONLIBDIR) || install -m 755 -d $(DESTDIR)$(PYTHONLIBDIR) install -m 755 $(SWIGSO) $(DESTDIR)$(PYTHONLIBDIR)/_semanage$(PYCEXT) install -m 644 semanage.py $(DESTDIR)$(PYTHONLIBDIR) install-rubywrap: rubywrap test -d $(DESTDIR)$(RUBYINSTALL) || install -m 755 -d $(DESTDIR)$(RUBYINSTALL) install -m 755 $(SWIGRUBYSO) $(DESTDIR)$(RUBYINSTALL)/semanage.so relabel: /sbin/restorecon $(DESTDIR)$(LIBDIR)/$(LIBSO) clean: -rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(SWIGRUBYSO) $(TARGET) conf-parse.c conf-parse.h conf-scan.c *.o *.lo *~ distclean: clean rm -f $(GENERATED) $(SWIGFILES) indent: ../../scripts/Lindent $(filter-out $(GENERATED),$(wildcard *.[ch])) .PHONY: all clean pywrap rubywrap swigify install install-pywrap install-rubywrap distclean libsemanage-3.8.1/src/boolean_internal.h000066400000000000000000000016061476211737200202620ustar00rootroot00000000000000#ifndef _SEMANAGE_BOOLEAN_INTERNAL_H_ #define _SEMANAGE_BOOLEAN_INTERNAL_H_ #include #include #include #include #include "database.h" #include "handle.h" /* BOOL RECORD: method table */ extern const record_table_t SEMANAGE_BOOL_RTABLE; extern int bool_file_dbase_init(semanage_handle_t * handle, const char *path_ro, const char *path_rw, 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-3.8.1/src/boolean_record.c000066400000000000000000000075471476211737200177310ustar00rootroot00000000000000/* 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 #include #include #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 /* 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); } void semanage_bool_key_free(semanage_bool_key_t * key) { sepol_bool_key_free(key); } int semanage_bool_compare(const semanage_bool_t * boolean, const semanage_bool_key_t * key) { return sepol_bool_compare(boolean, key); } int semanage_bool_compare2(const semanage_bool_t * boolean, const semanage_bool_t * boolean2) { return sepol_bool_compare2(boolean, boolean2); } static int semanage_bool_compare2_qsort(const void *p1, const void *p2) { const semanage_bool_t *const *boolean1 = p1; const semanage_bool_t *const *boolean2 = p2; return sepol_bool_compare2(*boolean1, *boolean2); } /* Name */ const char *semanage_bool_get_name(const semanage_bool_t * boolean) { return sepol_bool_get_name(boolean); } int semanage_bool_set_name(semanage_handle_t * handle, semanage_bool_t * boolean, const char *name) { int rc = -1; const char *prefix = semanage_root(); const char *storename = handle->conf->store_path; const char *selinux_root = selinux_policy_root(); char *oldroot; char *olddir; char *subname = NULL; char *newroot = NULL; char *end; if (!selinux_root) return -1; oldroot = strdup(selinux_root); if (!oldroot) return -1; olddir = strdup(oldroot); if (!olddir) goto out; end = strrchr(olddir, '/'); if (!end) goto out; end++; *end = '\0'; rc = asprintf(&newroot, "%s%s%s", prefix, olddir, storename); if (rc < 0) { newroot = NULL; goto out; } if (strcmp(oldroot, newroot)) { rc = selinux_set_policy_root(newroot); if (rc) goto out; } subname = selinux_boolean_sub(name); if (!subname) { rc = -1; goto out; } if (strcmp(oldroot, newroot)) { rc = selinux_set_policy_root(oldroot); if (rc) goto out; } rc = sepol_bool_set_name(handle->sepolh, boolean, subname); out: free(subname); free(oldroot); free(olddir); free(newroot); return rc; } /* Value */ int semanage_bool_get_value(const semanage_bool_t * boolean) { return sepol_bool_get_value(boolean); } void semanage_bool_set_value(semanage_bool_t * boolean, int value) { sepol_bool_set_value(boolean, 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); } 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); } void semanage_bool_free(semanage_bool_t * boolean) { sepol_bool_free(boolean); } /* Record base functions */ const 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-3.8.1/src/booleans_active.c000066400000000000000000000033371476211737200201020ustar00rootroot00000000000000/* 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-3.8.1/src/booleans_activedb.c000066400000000000000000000071761476211737200204150ustar00rootroot00000000000000/* 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 */ static const 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-3.8.1/src/booleans_file.c000066400000000000000000000056611476211737200175500ustar00rootroot00000000000000/* 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, const 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) < 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 */ static const 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 *path_ro, const char *path_rw, dbase_config_t * dconfig) { if (dbase_file_init(handle, path_ro, path_rw, &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-3.8.1/src/booleans_local.c000066400000000000000000000036521476211737200177210ustar00rootroot00000000000000/* 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-3.8.1/src/booleans_policy.c000066400000000000000000000026501476211737200201230ustar00rootroot00000000000000/* 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-3.8.1/src/booleans_policydb.c000066400000000000000000000046131476211737200204320ustar00rootroot00000000000000/* * 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" #include "semanage_store.h" /* BOOLEAN RECRORD (SEPOL): POLICYDB extension: method table */ static const record_policydb_table_t SEMANAGE_BOOL_POLICYDB_RTABLE = { .add = NULL, .modify = NULL, /* FIXME: these casts depend on structs 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, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL), semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), &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-3.8.1/src/compressed_file.c000066400000000000000000000123051476211737200201030ustar00rootroot00000000000000/* Author: Jason Tang * Christopher Ashworth * Ondrej Mosnacek * * Copyright (C) 2004-2006 Tresys Technology, LLC * Copyright (C) 2005-2021 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 "compressed_file.h" #include "debug.h" #define BZ2_MAGICSTR "BZh" #define BZ2_MAGICLEN (sizeof(BZ2_MAGICSTR)-1) /* 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 int bzip(semanage_handle_t *sh, const char *filename, void *data, size_t num_bytes) { BZFILE* b; size_t size = 1<<16; int bzerror; size_t total = 0; size_t len; FILE *f; if ((f = fopen(filename, "wbe")) == NULL) { return -1; } if (!sh->conf->bzip_blocksize) { if (fwrite(data, 1, num_bytes, f) < num_bytes) { fclose(f); return -1; } fclose(f); return 0; } b = BZ2_bzWriteOpen( &bzerror, f, sh->conf->bzip_blocksize, 0, 0); if (bzerror != BZ_OK) { BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 ); fclose(f); return -1; } while ( num_bytes > total ) { if (num_bytes - total > size) { len = size; } else { len = num_bytes - total; } BZ2_bzWrite ( &bzerror, b, (uint8_t *)data + total, len ); if (bzerror == BZ_IO_ERROR) { BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 ); fclose(f); return -1; } total += len; } BZ2_bzWriteClose ( &bzerror, b, 0, 0, 0 ); fclose(f); if (bzerror == BZ_IO_ERROR) { return -1; } return 0; } /* bunzip() a file to '*data', returning the total number of uncompressed bytes * in the file. Returns -1 if file could not be decompressed. */ static ssize_t bunzip(semanage_handle_t *sh, FILE *f, void **data) { BZFILE* b = NULL; size_t nBuf; uint8_t* buf = NULL; size_t size = 1<<18; size_t bufsize = size; int bzerror; size_t total = 0; uint8_t* uncompress = NULL; uint8_t* tmpalloc = NULL; ssize_t ret = -1; buf = malloc(bufsize); if (buf == NULL) { ERR(sh, "Failure allocating memory."); goto exit; } /* Check if the file is bzipped */ bzerror = fread(buf, 1, BZ2_MAGICLEN, f); if (fseek(f, 0L, SEEK_SET) == -1) { ERR(sh, "Failure rewinding file."); goto exit; } if ((bzerror != BZ2_MAGICLEN) || memcmp(buf, BZ2_MAGICSTR, BZ2_MAGICLEN)) { goto exit; } b = BZ2_bzReadOpen ( &bzerror, f, 0, sh->conf->bzip_small, NULL, 0 ); if ( bzerror != BZ_OK ) { ERR(sh, "Failure opening bz2 archive."); goto exit; } uncompress = malloc(size); if (uncompress == NULL) { ERR(sh, "Failure allocating memory."); goto exit; } while ( bzerror == BZ_OK) { nBuf = BZ2_bzRead ( &bzerror, b, buf, bufsize); if (( bzerror == BZ_OK ) || ( bzerror == BZ_STREAM_END )) { if (total + nBuf > size) { size *= 2; tmpalloc = realloc(uncompress, size); if (tmpalloc == NULL) { ERR(sh, "Failure allocating memory."); goto exit; } uncompress = tmpalloc; } memcpy(&uncompress[total], buf, nBuf); total += nBuf; } } if ( bzerror != BZ_STREAM_END ) { ERR(sh, "Failure reading bz2 archive."); goto exit; } ret = total; *data = uncompress; exit: BZ2_bzReadClose ( &bzerror, b ); free(buf); if ( ret < 0 ) { free(uncompress); } return ret; } int map_compressed_file(semanage_handle_t *sh, const char *path, struct file_contents *contents) { ssize_t size = -1; void *uncompress; int ret = 0, fd = -1; FILE *file = NULL; fd = open(path, O_RDONLY | O_CLOEXEC); if (fd == -1) { ERR(sh, "Unable to open %s.", path); return -1; } file = fdopen(fd, "r"); if (file == NULL) { ERR(sh, "Unable to open %s.", path); close(fd); return -1; } if ((size = bunzip(sh, file, &uncompress)) >= 0) { contents->data = uncompress; contents->len = size; contents->compressed = 1; } else { struct stat sb; if (fstat(fd, &sb) == -1 || (uncompress = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) { ret = -1; } else { contents->data = uncompress; contents->len = sb.st_size; contents->compressed = 0; } } fclose(file); return ret; } void unmap_compressed_file(struct file_contents *contents) { if (!contents->data) return; if (contents->compressed) { free(contents->data); } else { munmap(contents->data, contents->len); } } int write_compressed_file(semanage_handle_t *sh, const char *path, void *data, size_t len) { return bzip(sh, path, data, len); } libsemanage-3.8.1/src/compressed_file.h000066400000000000000000000050121476211737200201050ustar00rootroot00000000000000/* Author: Jason Tang * Christopher Ashworth * Ondrej Mosnacek * * Copyright (C) 2004-2006 Tresys Technology, LLC * Copyright (C) 2005-2021 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_CIL_FILE_H_ #define _SEMANAGE_CIL_FILE_H_ #include #include #include "handle.h" struct file_contents { void *data; /** file contents (uncompressed) */ size_t len; /** length of contents */ int compressed; /** whether file was compressed */ }; /** * Map/read a possibly-compressed file into memory. * * If the file is bzip compressed map_file will uncompress the file into * @p contents. The caller is responsible for calling * @ref unmap_compressed_file on @p contents on success. * * @param sh semanage handle * @param path path to the file * @param contents pointer to struct file_contents, which will be * populated with data pointer, size, and an indication whether * the file was compressed or not * * @return 0 on success, -1 otherwise. */ int map_compressed_file(semanage_handle_t *sh, const char *path, struct file_contents *contents); /** * Destroy a previously mapped possibly-compressed file. * * If all fields of @p contents are zero/NULL, the function is * guaranteed to do nothing. * * @param contents pointer to struct file_contents to destroy */ void unmap_compressed_file(struct file_contents *contents); /** * Write bytes into a file, using compression if configured. * * @param sh semanage handle * @param path path to the file * @param data pointer to the data * @param len length of the data * * @return 0 on success, -1 otherwise. */ int write_compressed_file(semanage_handle_t *sh, const char *path, void *data, size_t len); #endif libsemanage-3.8.1/src/conf-parse.y000066400000000000000000000441761476211737200170360ustar00rootroot00000000000000/* 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 #include #include #include #include #include #include #include extern int semanage_lex(void); /* defined in conf-scan.c */ extern int semanage_lex_destroy(void); /* defined in conf-scan.c */ int semanage_error(const char *msg); extern FILE *semanage_in; extern char *semanage_text; static int parse_module_store(char *arg); static int parse_store_root_path(char *arg); static int parse_compiler_path(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 TARGET_PLATFORM COMPILER_DIR IGNORE_MODULE_CACHE STORE_ROOT OPTIMIZE_POLICY MULTIPLE_DECLS %token LOAD_POLICY_START SETFILES_START SEFCONTEXT_COMPILE_START DISABLE_GENHOMEDIRCON HANDLE_UNKNOWN USEPASSWD IGNOREDIRS %token BZIP_BLOCKSIZE BZIP_SMALL REMOVE_HLL %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 | target_platform | store_root | compiler_dir | ignore_module_cache | expand_check | file_mode | save_previous | save_linked | disable_genhomedircon | usepasswd | ignoredirs | handle_unknown | bzip_blocksize | bzip_small | remove_hll | optimize_policy | multiple_decls ; module_store: MODULE_STORE '=' ARG { if (parse_module_store($3) != 0) { parse_errors++; YYABORT; } free($3); } ; store_root: STORE_ROOT '=' ARG { if (parse_store_root_path($3) != 0) { parse_errors++; YYABORT; } free($3); } ; compiler_dir: COMPILER_DIR '=' ARG { if (parse_compiler_path($3) != 0) { parse_errors++; YYABORT; } free($3); } ; ignore_module_cache: IGNORE_MODULE_CACHE '=' ARG { if (strcasecmp($3, "true") == 0) current_conf->ignore_module_cache = 1; else if (strcasecmp($3, "false") == 0) current_conf->ignore_module_cache = 0; else { yyerror("disable-caching can only be 'true' or 'false'"); } free($3); } ; version: VERSION '=' ARG { char *endptr; long value; errno = 0; value = strtol($3, &endptr, 10); if (*endptr != '\0' || errno != 0 || value < sepol_policy_kern_vers_min() || value > sepol_policy_kern_vers_max()) yyerror("policy-version must be a valid policy version"); else current_conf->policyvers = value; free($3); } ; target_platform: TARGET_PLATFORM '=' ARG { if (strcasecmp($3, "selinux") == 0) current_conf->target_platform = SEPOL_TARGET_SELINUX; else if (strcasecmp($3, "xen") == 0) current_conf->target_platform = SEPOL_TARGET_XEN; else { yyerror("target_platform can only be 'selinux' or 'xen'"); } free($3); } ; expand_check: EXPAND_CHECK '=' ARG { char *endptr; long value; errno = 0; value = strtol($3, &endptr, 10); if (*endptr != '\0' || errno != 0 || (value != 0 && value != 1)) yyerror("expand-check can only be '1' or '0'"); else current_conf->expand_check = value; free($3); } ; file_mode: FILE_MODE '=' ARG { char *endptr; long value; errno = 0; value = strtol($3, &endptr, 8); if (*endptr != '\0' || errno != 0 || value < 0 || value > 0777) yyerror("file-mode must be a valid permission mode"); else current_conf->file_mode = value; 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'"); } free($3); } ; 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'"); } free($3); } ; 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); free($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 { char *endptr; long value; errno = 0; value = strtol($3, &endptr, 10); if (*endptr != '\0' || errno != 0 || value < 0 || value > 9) yyerror("bzip-blocksize can only be in the range 0-9"); else current_conf->bzip_blocksize = value; free($3); } 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); } remove_hll: REMOVE_HLL'=' ARG { if (strcasecmp($3, "false") == 0) { current_conf->remove_hll = 0; } else if (strcasecmp($3, "true") == 0) { current_conf->remove_hll = 1; } else { yyerror("remove-hll can only be 'true' or 'false'"); } free($3); } optimize_policy: OPTIMIZE_POLICY '=' ARG { if (strcasecmp($3, "false") == 0) { current_conf->optimize_policy = 0; } else if (strcasecmp($3, "true") == 0) { current_conf->optimize_policy = 1; } else { yyerror("optimize-policy can only be 'true' or 'false'"); } free($3); } multiple_decls: MULTIPLE_DECLS '=' ARG { if (strcasecmp($3, "false") == 0) { current_conf->multiple_decls = 0; } else if (strcasecmp($3, "true") == 0) { current_conf->multiple_decls = 1; } else { yyerror("multiple-decls 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(selinux_policy_root())); conf->ignoredirs = NULL; conf->store_root_path = strdup("/var/lib/selinux"); conf->compiler_directory_path = strdup("/usr/libexec/selinux/hll"); conf->policyvers = sepol_policy_kern_vers_max(); conf->target_platform = SEPOL_TARGET_SELINUX; conf->expand_check = 1; conf->handle_unknown = -1; conf->usepasswd = 1; conf->file_mode = 0644; conf->bzip_blocksize = 9; conf->bzip_small = 0; conf->ignore_module_cache = 0; conf->remove_hll = 0; conf->optimize_policy = 1; conf->multiple_decls = 1; conf->save_previous = 0; conf->save_linked = 0; if (!conf->store_path || !conf->store_root_path || !conf->compiler_directory_path) { return -1; } 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, "re")) == 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); semanage_lex_destroy(); 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); free(conf->store_root_path); free(conf->compiler_directory_path); 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(const 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(selinux_policy_root())); current_conf->server_port = -1; } else if (*arg == '/') { current_conf->store_type = SEMANAGE_CON_POLSERV_LOCAL; current_conf->store_path = strdup(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 = strdup(arg); current_conf->server_port = 4242; } else { char *endptr; *s = '\0'; current_conf->store_path = strdup(arg); current_conf->server_port = strtol(s + 1, &endptr, 10); if (*(s + 1) == '\0' || *endptr != '\0') { return -2; } } } return 0; } static int parse_store_root_path(char *arg) { if (arg == NULL) { return -1; } free(current_conf->store_root_path); current_conf->store_root_path = strdup(arg); return 0; } static int parse_compiler_path(char *arg) { if (arg == NULL) { return -1; } free(current_conf->compiler_directory_path); current_conf->compiler_directory_path = strdup(arg); 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-3.8.1/src/conf-scan.l000066400000000000000000000063161476211737200166250ustar00rootroot00000000000000/* 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); %} %option stack prefix="semanage_" %option noinput nounput noyy_push_state noyy_pop_state noyy_top_state noyywrap %x arg %% #.* /* ignore comments */ module-store return MODULE_STORE; store-root return STORE_ROOT; compiler-directory return COMPILER_DIR; ignore-module-cache return IGNORE_MODULE_CACHE; policy-version return VERSION; target-platform return TARGET_PLATFORM; 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; remove-hll return REMOVE_HLL; optimize-policy return OPTIMIZE_POLICY; multiple-decls return MULTIPLE_DECLS; "[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; %% /* Like strdup(), but also trim leading and trailing whitespace. * Returns NULL on error. */ static char *my_strdup(char *s) { char *t; while (isspace((unsigned char)*s)) { s++; } t = s + strlen(s) - 1; while (t >= s && isspace((unsigned char)*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-3.8.1/src/context_record.c000066400000000000000000000043411476211737200177630ustar00rootroot00000000000000/* Copyright (C) 2005 Red Hat, Inc. */ #include #include "handle.h" typedef sepol_context_t semanage_context_t; #define _SEMANAGE_CONTEXT_DEFINED_ #include /* 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); } void semanage_context_free(semanage_context_t * con) { sepol_context_free(con); } /* 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); } 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); } libsemanage-3.8.1/src/database.c000066400000000000000000000101701476211737200165020ustar00rootroot00000000000000/* 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, const 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-3.8.1/src/database.h000066400000000000000000000153251476211737200165160ustar00rootroot00000000000000/* 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 void * rec, const void * 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 successfully 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 * occurred 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. */ const record_table_t *(*get_rtable) (dbase_t * dbase); } dbase_table_t; typedef struct dbase_config { /* Database state */ dbase_t *dbase; /* Database methods */ const 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-3.8.1/src/database_activedb.c000066400000000000000000000077751476211737200203640ustar00rootroot00000000000000/* 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 */ const record_activedb_table_t *ratable; }; static int dbase_activedb_cache(semanage_handle_t * handle, dbase_activedb_t * dbase) { const record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist); const 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) { const record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist); const 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, const record_table_t * rtable, const 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) { if (!dbase) return; dbase_llist_drop_cache(&dbase->llist); free(dbase); } /* ACTIVEDB dbase - method table implementation */ const 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-3.8.1/src/database_activedb.h000066400000000000000000000020361476211737200203520ustar00rootroot00000000000000/* 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, const record_table_t * rtable, const 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 const dbase_table_t SEMANAGE_ACTIVEDB_DTABLE; #endif libsemanage-3.8.1/src/database_file.c000066400000000000000000000120131476211737200174770ustar00rootroot00000000000000/* 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 path for read-only[0] and transaction[1] */ const char *path[2]; /* FILE extension */ const record_file_table_t *rftable; }; static int dbase_file_cache(semanage_handle_t * handle, dbase_file_t * dbase) { const record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist); const record_file_table_t *rftable = dbase->rftable; record_t *process_record = NULL; int pstatus = STATUS_SUCCESS; parse_info_t *parse_info = NULL; const 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; fname = dbase->path[handle->is_in_transaction]; 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); 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); return STATUS_ERR; } /* Flush database to file */ static int dbase_file_flush(semanage_handle_t * handle, dbase_file_t * dbase) { const record_file_table_t *rftable = dbase->rftable; cache_entry_t *ptr; const char *fname = NULL; FILE *str = NULL; mode_t mask; if (!dbase_llist_is_modified(&dbase->llist)) return STATUS_SUCCESS; fname = dbase->path[handle->is_in_transaction]; mask = umask(0077); str = fopen(fname, "we"); umask(mask); if (!str) { ERR(handle, "could not open %s for writing", fname); 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); if (fclose(str) != 0 && errno != EINTR) { str = NULL; goto err; } return STATUS_SUCCESS; err: if (str != NULL) fclose(str); ERR(handle, "could not flush database to file"); return STATUS_ERR; } int dbase_file_init(semanage_handle_t * handle, const char *path_ro, const char *path_rw, const record_table_t * rtable, const 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->path[0] = path_ro; tmp_dbase->path[1] = path_rw; 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) { if (!dbase) return; dbase_llist_drop_cache(&dbase->llist); free(dbase); } /* FILE dbase - method table implementation */ dbase_table_t const 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-3.8.1/src/database_file.h000066400000000000000000000022571476211737200175150ustar00rootroot00000000000000/* 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, const record_t * record, FILE * str); } record_file_table_t; /* FILE - initialization */ extern int dbase_file_init(semanage_handle_t * handle, const char *path_ro, const char *path_rw, const record_table_t * rtable, const 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 const dbase_table_t SEMANAGE_FILE_DTABLE; #endif libsemanage-3.8.1/src/database_join.c000066400000000000000000000166051476211737200175320ustar00rootroot00000000000000/* 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 */ const 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; const dbase_table_t *dtable1 = dbase->join1->dtable; const dbase_table_t *dtable2 = dbase->join2->dtable; const record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist); const record_join_table_t *rjtable = dbase->rjtable; const record_table_t *rtable1 = dtable1->get_rtable(dbase1); const 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 */ if (rcount1 > 1) { qsort(records1, rcount1, sizeof(record1_t *), rtable1->compare2_qsort); } if (rcount2 > 1) { qsort(records2, rcount2, sizeof(record2_t *), 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; const dbase_table_t *dtable1 = dbase->join1->dtable; const dbase_table_t *dtable2 = dbase->join2->dtable; const record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist); const record_join_table_t *rjtable = dbase->rjtable; const record_table_t *rtable1 = dtable1->get_rtable(dbase1); const 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, const record_table_t * rtable, const 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) { if (!dbase) return; dbase_llist_drop_cache(&dbase->llist); free(dbase); } /* JOIN dbase - method table implementation */ const 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-3.8.1/src/database_join.h000066400000000000000000000023641476211737200175340ustar00rootroot00000000000000/* 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, const record_table_t * rtable, const 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 const dbase_table_t SEMANAGE_JOIN_DTABLE; #endif libsemanage-3.8.1/src/database_llist.c000066400000000000000000000171471476211737200177240ustar00rootroot00000000000000/* 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; 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; } int dbase_llist_count(semanage_handle_t * handle __attribute__ ((unused)), dbase_llist_t * dbase, unsigned int *response) { *response = dbase->cache_sz; 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 > 0) 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; } 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-3.8.1/src/database_llist.h000066400000000000000000000062521476211737200177240ustar00rootroot00000000000000/* 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 */ const record_table_t *rtable; const 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, const record_table_t * rtable, const 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(const dbase_llist_t * dbase) { return dbase->modified; } /* LLIST - polymorphism */ static inline const record_table_t *dbase_llist_get_rtable(const 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-3.8.1/src/database_policydb.c000066400000000000000000000237271476211737200204030ustar00rootroot00000000000000/* 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 path for read-only[0] and transaction[1] */ const char *path[2]; /* Base record table */ const record_table_t *rtable; /* Policy extensions */ const 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 && 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 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; const char *fname = NULL; /* Check if cache is needed */ if (dbase->attached) return STATUS_SUCCESS; if (!dbase_policydb_needs_resync(handle, dbase)) return STATUS_SUCCESS; fname = dbase->path[handle->is_in_transaction]; 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, "rbe"); if (fp == NULL && errno != ENOENT) { ERR(handle, "could not open %s for reading", fname); 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; return STATUS_SUCCESS; err: ERR(handle, "could not cache policy database"); if (fp) fclose(fp); sepol_policydb_free(policydb); sepol_policy_file_free(pf); 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 */ 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 *path_ro, const char *path_rw, const record_table_t * rtable, const 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->path[0] = path_ro; tmp_dbase->path[1] = path_rw; 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 */ return STATUS_ERR; } static int dbase_policydb_clear(semanage_handle_t * handle __attribute__ ((unused)), dbase_policydb_t * dbase __attribute__ ((unused))) { /* Stub */ 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; const 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 const record_table_t *dbase_policydb_get_rtable(dbase_policydb_t * dbase) { return dbase->rtable; } /* POLICYDB dbase - method table implementation */ const 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-3.8.1/src/database_policydb.h000066400000000000000000000073341476211737200204040ustar00rootroot00000000000000/* * 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 *path_ro, const char *path_rw, const record_table_t * rtable, const 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 const dbase_table_t SEMANAGE_POLICYDB_DTABLE; #endif libsemanage-3.8.1/src/debug.c000066400000000000000000000060631476211737200160320ustar00rootroot00000000000000/* 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; } const char *semanage_msg_get_channel(semanage_handle_t * handle) { return handle->msg_channel; } const char *semanage_msg_get_fname(semanage_handle_t * handle) { return handle->msg_fname; } #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif void 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) { errno = errsv; fprintf(stream, " (%m)."); } fprintf(stream, "\n"); } #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif void 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); } 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-3.8.1/src/debug.h000066400000000000000000000055401476211737200160360ustar00rootroot00000000000000/* 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 #include "handle.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) { \ int errsv__ = errno; \ \ (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__); \ \ errno = errsv__; \ } \ } 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 semanage_msg_default_handler(void *varg, semanage_handle_t * handle, const char *fmt, ...); #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif extern void semanage_msg_relay_handler(void *varg, sepol_handle_t * handle, const char *fmt, ...); #endif libsemanage-3.8.1/src/direct_api.c000066400000000000000000002224271476211737200170530ustar00rootroot00000000000000/* Author: 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 */ #include #include #include #include #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 "ibpkey_internal.h" #include "ibendport_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 "compressed_file.h" #include "modules.h" #include "direct_api.h" #include "semanage_store.h" #include "database_policydb.h" #include "policy.h" #include "sha256.h" #define PIPE_READ 0 #define PIPE_WRITE 1 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 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, const char *module_name, const char *lang_ext); static int semanage_direct_install_file(semanage_handle_t * sh, const char *module_name); static int semanage_direct_extract(semanage_handle_t * sh, semanage_module_key_t *modkey, int extract_cil, void **mapped_data, size_t *data_len, semanage_module_info_t **modinfo); 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 int semanage_direct_get_enabled(semanage_handle_t *sh, const semanage_module_key_t *modkey, int *enabled); static int semanage_direct_set_enabled(semanage_handle_t *sh, const semanage_module_key_t *modkey, int enabled); static int semanage_direct_get_module_info(semanage_handle_t *sh, const semanage_module_key_t *modkey, semanage_module_info_t **modinfo); static int semanage_direct_list_all(semanage_handle_t *sh, semanage_module_info_t **modinfo, int *num_modules); static int semanage_direct_install_info(semanage_handle_t *sh, const semanage_module_info_t *modinfo, char *data, size_t data_len); static int semanage_direct_remove_key(semanage_handle_t *sh, const semanage_module_key_t *modkey); static const 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, .extract = semanage_direct_extract, .install_file = semanage_direct_install_file, .remove = semanage_direct_remove, .list = semanage_direct_list, .get_enabled = semanage_direct_get_enabled, .set_enabled = semanage_direct_set_enabled, .get_module_info = semanage_direct_get_module_info, .list_all = semanage_direct_list_all, .install_info = semanage_direct_install_info, .remove_key = semanage_direct_remove_key, }; int semanage_direct_is_managed(semanage_handle_t * sh) { if (semanage_check_init(sh, sh->conf->store_root_path)) 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) { const char *path; struct stat sb; if (semanage_check_init(sh, sh->conf->store_root_path)) goto err; if (sh->create_store) if (semanage_create_store(sh, 1)) 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_path(SEMANAGE_ACTIVE, SEMANAGE_USERS_BASE_LOCAL), semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_BASE_LOCAL), semanage_user_base_dbase_local(sh)) < 0) goto err; if (user_extra_file_dbase_init(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_USERS_EXTRA_LOCAL), semanage_path(SEMANAGE_TMP, 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_path(SEMANAGE_ACTIVE, SEMANAGE_PORTS_LOCAL), semanage_path(SEMANAGE_TMP, SEMANAGE_PORTS_LOCAL), semanage_port_dbase_local(sh)) < 0) goto err; if (iface_file_dbase_init(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_INTERFACES_LOCAL), semanage_path(SEMANAGE_TMP, SEMANAGE_INTERFACES_LOCAL), semanage_iface_dbase_local(sh)) < 0) goto err; if (bool_file_dbase_init(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_BOOLEANS_LOCAL), semanage_path(SEMANAGE_TMP, SEMANAGE_BOOLEANS_LOCAL), semanage_bool_dbase_local(sh)) < 0) goto err; if (fcontext_file_dbase_init(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC_LOCAL), semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL), semanage_fcontext_dbase_local(sh)) < 0) goto err; if (fcontext_file_dbase_init(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC_HOMEDIRS), semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS), semanage_fcontext_dbase_homedirs(sh)) < 0) goto err; if (seuser_file_dbase_init(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_SEUSERS_LOCAL), semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LOCAL), semanage_seuser_dbase_local(sh)) < 0) goto err; if (node_file_dbase_init(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_NODES_LOCAL), semanage_path(SEMANAGE_TMP, SEMANAGE_NODES_LOCAL), semanage_node_dbase_local(sh)) < 0) goto err; if (ibpkey_file_dbase_init(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_IBPKEYS_LOCAL), semanage_path(SEMANAGE_TMP, SEMANAGE_IBPKEYS_LOCAL), semanage_ibpkey_dbase_local(sh)) < 0) goto err; if (ibendport_file_dbase_init(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_IBENDPORTS_LOCAL), semanage_path(SEMANAGE_TMP, SEMANAGE_IBENDPORTS_LOCAL), semanage_ibendport_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_path(SEMANAGE_ACTIVE, SEMANAGE_USERS_EXTRA), semanage_path(SEMANAGE_TMP, 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 (ibpkey_policydb_dbase_init(sh, semanage_ibpkey_dbase_policy(sh)) < 0) goto err; if (ibendport_policydb_dbase_init(sh, semanage_ibendport_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_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC), semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC), semanage_fcontext_dbase_policy(sh)) < 0) goto err; if (seuser_file_dbase_init(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_SEUSERS), semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_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 (stat(path, &sb) == 0) sepol_set_disable_dontaudit(sh->sepolh, 1); else if (errno == ENOENT) { /* The file does not exist */ sepol_set_disable_dontaudit(sh->sepolh, 0); } else { ERR(sh, "Unable to access %s.", path); goto err; } return STATUS_SUCCESS; err: ERR(sh, "could not establish direct connection"); (void) semanage_direct_disconnect(sh); return STATUS_ERR; } static void semanage_direct_destroy(semanage_handle_t * sh __attribute__ ((unused))) { /* do nothing */ } static int semanage_remove_tmps(semanage_handle_t *sh) { if (sh->commit_err) return 0; /* destroy sandbox if it exists */ if (semanage_remove_directory (semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)) < 0) { if (errno != ENOENT) { ERR(sh, "Could not cleanly remove sandbox %s.", semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)); return -1; } } /* destroy tmp policy if it exists */ if (semanage_remove_directory (semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FINAL_TOPLEVEL)) < 0) { if (errno != ENOENT) { ERR(sh, "Could not cleanly remove tmp %s.", semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FINAL_TOPLEVEL)); return -1; } } return 0; } static int semanage_direct_disconnect(semanage_handle_t *sh) { int retval = 0; /* destroy transaction and remove tmp files if no commit error */ if (sh->is_in_transaction) { retval = semanage_remove_tmps(sh); 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)); ibpkey_file_dbase_release(semanage_ibpkey_dbase_local(sh)); ibendport_file_dbase_release(semanage_ibendport_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)); fcontext_file_dbase_release(semanage_fcontext_dbase_homedirs(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)); ibpkey_policydb_dbase_release(semanage_ibpkey_dbase_policy(sh)); ibendport_policydb_dbase_release(semanage_ibendport_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 retval; } static int semanage_direct_begintrans(semanage_handle_t * sh) { if (semanage_get_trans_lock(sh) < 0) { return -1; } if ((semanage_make_sandbox(sh)) < 0) { return -1; } if ((semanage_make_final(sh)) < 0) { return -1; } return 0; } /********************* utility functions *********************/ /* Takes a module stored in 'module_data' and parses its headers. * Sets reference variables 'module_name' to module's name, and * 'version' to module's version. The caller is responsible for * free()ing 'module_name', and 'version'; they will be * set to NULL upon entering this function. Returns 0 on success, -1 * if out of memory. */ static int parse_module_headers(semanage_handle_t * sh, char *module_data, size_t data_len, char **module_name, char **version) { struct sepol_policy_file *pf; int file_type; *module_name = *version = 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); sepol_policy_file_free(pf); return 0; } /* 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, const char *data, size_t num_bytes) { int out; if ((out = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IWUSR)) == -1) { ERR(sh, "Could not open %s for writing.", filename); return -1; } if (write_full(out, data, num_bytes) == -1) { ERR(sh, "Error while writing to %s.", filename); close(out); return -1; } if (close(out) == -1 && errno != EINTR) { ERR(sh, "Error while closing %s.", filename); return -1; } return 0; } static int semanage_direct_update_user_extra(semanage_handle_t * sh, cil_db_t *cildb) { const char *ofilename = NULL; int retval = -1; char *data = NULL; size_t size = 0; dbase_config_t *pusers_extra = semanage_user_extra_dbase_policy(sh); retval = cil_userprefixes_to_string(cildb, &data, &size); if (retval != SEPOL_OK) { goto cleanup; } if (size > 0) { /* * Write the users_extra entries from CIL modules. * This file is used as our baseline when we do not require * re-linking. */ ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED); if (ofilename == NULL) { retval = -1; goto cleanup; } retval = write_file(sh, ofilename, data, size); if (retval < 0) goto cleanup; /* * Write the users_extra file; users_extra.local * will be merged into this file. */ ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA); if (ofilename == NULL) { retval = -1; goto cleanup; } retval = write_file(sh, ofilename, data, size); if (retval < 0) goto cleanup; pusers_extra->dtable->drop_cache(pusers_extra->dbase); } else { retval = pusers_extra->dtable->clear(sh, pusers_extra->dbase); } cleanup: free(data); return retval; } static int semanage_direct_update_seuser(semanage_handle_t * sh, cil_db_t *cildb) { const char *ofilename = NULL; int retval = -1; char *data = NULL; size_t size = 0; dbase_config_t *pseusers = semanage_seuser_dbase_policy(sh); retval = cil_selinuxusers_to_string(cildb, &data, &size); if (retval != SEPOL_OK) { goto cleanup; } if (size > 0) { /* * Write the seusers entries from CIL modules. * This file is used as our baseline when we do not require * re-linking. */ ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED); if (ofilename == NULL) { retval = -1; goto cleanup; } retval = write_file(sh, ofilename, data, size); if (retval < 0) goto cleanup; /* * Write the seusers file; seusers.local will be merged into * this file. */ ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS); if (ofilename == NULL) { retval = -1; goto cleanup; } retval = write_file(sh, ofilename, data, size); if (retval < 0) goto cleanup; pseusers->dtable->drop_cache(pseusers->dbase); } else { retval = pseusers->dtable->clear(sh, pseusers->dbase); } cleanup: free(data); return retval; } static int read_from_pipe_to_data(semanage_handle_t *sh, size_t initial_len, int fd, char **out_data_read, size_t *out_read_len) { size_t max_len = initial_len; ssize_t read_len; size_t data_read_len = 0; char *data_read = NULL; if (max_len <= 0) { max_len = 1; } data_read = malloc(max_len * sizeof(*data_read)); if (data_read == NULL) { ERR(sh, "Failed to malloc, out of memory."); return -1; } while ((read_len = read(fd, data_read + data_read_len, max_len - data_read_len)) > 0) { data_read_len += read_len; if (data_read_len == max_len) { char *tmp; max_len *= 2; tmp = realloc(data_read, max_len); if (tmp == NULL) { ERR(sh, "Failed to realloc, out of memory."); free(data_read); return -1; } data_read = tmp; } } *out_read_len = data_read_len; *out_data_read = data_read; return 0; } static int semanage_pipe_data(semanage_handle_t *sh, const char *path, const char *in_data, size_t in_data_len, char **out_data, size_t *out_data_len, char **err_data, size_t *err_data_len) { int input_fd[2] = {-1, -1}; int output_fd[2] = {-1, -1}; int err_fd[2] = {-1, -1}; pid_t pid; char *data_read = NULL; char *err_data_read = NULL; int retval; int status = 0; size_t initial_len; size_t data_read_len = 0; size_t err_data_read_len = 0; struct sigaction old_signal; struct sigaction new_signal; new_signal.sa_handler = SIG_IGN; sigemptyset(&new_signal.sa_mask); new_signal.sa_flags = 0; /* This is needed in case the read end of input_fd is closed causing a SIGPIPE signal to be sent. * If SIGPIPE is not caught, the signal will cause semanage to terminate immediately. The sigaction below * creates a new_signal that ignores SIGPIPE allowing the write to exit cleanly. * * Another sigaction is called in cleanup to restore the original behavior when a SIGPIPE is received. */ sigaction(SIGPIPE, &new_signal, &old_signal); retval = pipe2(input_fd, O_CLOEXEC); if (retval == -1) { ERR(sh, "Unable to create pipe for input pipe."); goto cleanup; } retval = pipe2(output_fd, O_CLOEXEC); if (retval == -1) { ERR(sh, "Unable to create pipe for output pipe."); goto cleanup; } retval = pipe2(err_fd, O_CLOEXEC); if (retval == -1) { ERR(sh, "Unable to create pipe for error pipe."); goto cleanup; } pid = fork(); if (pid == -1) { ERR(sh, "Unable to fork from parent."); retval = -1; goto cleanup; } else if (pid == 0) { retval = dup2(input_fd[PIPE_READ], STDIN_FILENO); if (retval == -1) { ERR(sh, "Unable to dup2 input pipe."); goto cleanup; } retval = dup2(output_fd[PIPE_WRITE], STDOUT_FILENO); if (retval == -1) { ERR(sh, "Unable to dup2 output pipe."); goto cleanup; } retval = dup2(err_fd[PIPE_WRITE], STDERR_FILENO); if (retval == -1) { ERR(sh, "Unable to dup2 error pipe."); goto cleanup; } retval = close(input_fd[PIPE_WRITE]); if (retval == -1) { ERR(sh, "Unable to close input pipe."); goto cleanup; } retval = close(output_fd[PIPE_READ]); if (retval == -1) { ERR(sh, "Unable to close output pipe."); goto cleanup; } retval = close(err_fd[PIPE_READ]); if (retval == -1) { ERR(sh, "Unable to close error pipe."); goto cleanup; } retval = execl(path, path, NULL); if (retval == -1) { ERR(sh, "Unable to execute %s.", path); _exit(EXIT_FAILURE); } } else { retval = close(input_fd[PIPE_READ]); input_fd[PIPE_READ] = -1; if (retval == -1) { ERR(sh, "Unable to close read end of input pipe."); goto cleanup; } retval = close(output_fd[PIPE_WRITE]); output_fd[PIPE_WRITE] = -1; if (retval == -1) { ERR(sh, "Unable to close write end of output pipe."); goto cleanup; } retval = close(err_fd[PIPE_WRITE]); err_fd[PIPE_WRITE] = -1; if (retval == -1) { ERR(sh, "Unable to close write end of error pipe."); goto cleanup; } retval = write_full(input_fd[PIPE_WRITE], in_data, in_data_len); if (retval == -1) { ERR(sh, "Failed to write data to input pipe."); goto cleanup; } retval = close(input_fd[PIPE_WRITE]); input_fd[PIPE_WRITE] = -1; if (retval == -1) { ERR(sh, "Unable to close write end of input pipe."); goto cleanup; } initial_len = 1 << 17; retval = read_from_pipe_to_data(sh, initial_len, output_fd[PIPE_READ], &data_read, &data_read_len); if (retval != 0) { goto cleanup; } retval = close(output_fd[PIPE_READ]); output_fd[PIPE_READ] = -1; if (retval == -1) { ERR(sh, "Unable to close read end of output pipe."); goto cleanup; } initial_len = 1 << 9; retval = read_from_pipe_to_data(sh, initial_len, err_fd[PIPE_READ], &err_data_read, &err_data_read_len); if (retval != 0) { goto cleanup; } retval = close(err_fd[PIPE_READ]); err_fd[PIPE_READ] = -1; if (retval == -1) { ERR(sh, "Unable to close read end of error pipe."); goto cleanup; } if (waitpid(pid, &status, 0) == -1 || !WIFEXITED(status)) { ERR(sh, "Child process %s did not exit cleanly.", path); retval = -1; goto cleanup; } if (WEXITSTATUS(status) != 0) { ERR(sh, "Child process %s failed with code: %d.", path, WEXITSTATUS(status)); retval = -1; goto cleanup; } } retval = 0; cleanup: sigaction(SIGPIPE, &old_signal, NULL); if (data_read != NULL) { *out_data = data_read; *out_data_len = data_read_len; } if (err_data_read != NULL) { *err_data = err_data_read; *err_data_len = err_data_read_len; } if (output_fd[PIPE_READ] != -1) { close(output_fd[PIPE_READ]); } if (output_fd[PIPE_WRITE] != -1) { close(output_fd[PIPE_WRITE]); } if (err_fd[PIPE_READ] != -1) { close(err_fd[PIPE_READ]); } if (err_fd[PIPE_WRITE] != -1) { close(err_fd[PIPE_WRITE]); } if (input_fd[PIPE_READ] != -1) { close(input_fd[PIPE_READ]); } if (input_fd[PIPE_WRITE] != -1) { close(input_fd[PIPE_WRITE]); } return retval; } static int semanage_direct_write_langext(semanage_handle_t *sh, const char *lang_ext, const semanage_module_info_t *modinfo) { int ret = -1; char fn[PATH_MAX]; FILE *fp = NULL; ret = semanage_module_get_path(sh, modinfo, SEMANAGE_MODULE_PATH_LANG_EXT, fn, sizeof(fn)); if (ret != 0) { goto cleanup; } fp = fopen(fn, "we"); if (fp == NULL) { ERR(sh, "Unable to open %s module ext file.", modinfo->name); ret = -1; goto cleanup; } if (fputs(lang_ext, fp) < 0) { ERR(sh, "Unable to write %s module ext file.", modinfo->name); ret = -1; goto cleanup; } if (fclose(fp) != 0 && errno != EINTR) { ERR(sh, "Unable to close %s module ext file.", modinfo->name); fp = NULL; ret = -1; goto cleanup; } fp = NULL; ret = 0; cleanup: if (fp != NULL) fclose(fp); return ret; } static void update_checksum_with_len(Sha256Context *context, size_t s) { int i; uint8_t buffer[8]; for (i = 0; i < 8; i++) { buffer[i] = s & 0xff; s >>= 8; } Sha256Update(context, buffer, 8); } static void update_checksum_with_bool(Sha256Context *context, bool b) { uint8_t byte; byte = b ? UINT8_C(1) : UINT8_C(0); Sha256Update(context, &byte, 1); } static int semanage_compile_module(semanage_handle_t *sh, semanage_module_info_t *modinfo, Sha256Context *context) { char cil_path[PATH_MAX]; char hll_path[PATH_MAX]; char *compiler_path = NULL; char *cil_data = NULL; char *err_data = NULL; char *start = NULL; char *end = NULL; int status = 0; size_t cil_data_len = 0; size_t err_data_len = 0; struct file_contents hll_contents = {}; if (!strcasecmp(modinfo->lang_ext, "cil")) { goto cleanup; } status = semanage_get_hll_compiler_path(sh, modinfo->lang_ext, &compiler_path); if (status != 0) { goto cleanup; } status = semanage_module_get_path( sh, modinfo, SEMANAGE_MODULE_PATH_CIL, cil_path, sizeof(cil_path)); if (status != 0) { goto cleanup; } status = semanage_module_get_path( sh, modinfo, SEMANAGE_MODULE_PATH_HLL, hll_path, sizeof(hll_path)); if (status != 0) { goto cleanup; } status = map_compressed_file(sh, hll_path, &hll_contents); if (status < 0) { ERR(sh, "Unable to read file %s.", hll_path); goto cleanup; } status = semanage_pipe_data(sh, compiler_path, hll_contents.data, hll_contents.len, &cil_data, &cil_data_len, &err_data, &err_data_len); if (err_data_len > 0) { for (start = end = err_data; end < err_data + err_data_len; end++) { if (*end == '\n') { ERR(sh, "%s: %.*s.", modinfo->name, (int)(end - start + 1), start); start = end + 1; } } if (end != start) { ERR(sh, "%s: %.*s.", modinfo->name, (int)(end - start), start); } } if (status != 0) { goto cleanup; } if (context) { update_checksum_with_len(context, cil_data_len); Sha256Update(context, cil_data, cil_data_len); } status = write_compressed_file(sh, cil_path, cil_data, cil_data_len); if (status == -1) { ERR(sh, "Failed to write %s.", cil_path); goto cleanup; } if (sh->conf->remove_hll == 1) { status = unlink(hll_path); if (status != 0) { ERR(sh, "Error while removing HLL file %s.", hll_path); goto cleanup; } status = semanage_direct_write_langext(sh, "cil", modinfo); if (status != 0) { goto cleanup; } } cleanup: unmap_compressed_file(&hll_contents); free(cil_data); free(err_data); free(compiler_path); return status; } static int modinfo_cmp(const void *a, const void *b) { const semanage_module_info_t *ma = a; const semanage_module_info_t *mb = b; return strcmp(ma->name, mb->name); } struct extra_checksum_params { int disable_dontaudit; int preserve_tunables; int target_platform; int policyvers; }; static int semanage_compile_hll_modules(semanage_handle_t *sh, semanage_module_info_t *modinfos, int num_modinfos, const struct extra_checksum_params *extra, char *cil_checksum) { /* to be incremented when checksum input data format changes */ static const size_t CHECKSUM_EPOCH = 2; int i, status; char cil_path[PATH_MAX]; struct stat sb; Sha256Context context; SHA256_HASH hash; struct file_contents contents = {}; assert(sh); assert(modinfos); /* Sort modules by name to get consistent ordering. */ qsort(modinfos, num_modinfos, sizeof(*modinfos), &modinfo_cmp); Sha256Initialise(&context); update_checksum_with_len(&context, CHECKSUM_EPOCH); update_checksum_with_bool(&context, !!extra->disable_dontaudit); update_checksum_with_bool(&context, !!extra->preserve_tunables); update_checksum_with_len(&context, (size_t)extra->target_platform); update_checksum_with_len(&context, (size_t)extra->policyvers); /* prefix with module count to avoid collisions */ update_checksum_with_len(&context, num_modinfos); for (i = 0; i < num_modinfos; i++) { status = semanage_module_get_path( sh, &modinfos[i], SEMANAGE_MODULE_PATH_CIL, cil_path, sizeof(cil_path)); if (status != 0) return -1; if (!semanage_get_ignore_module_cache(sh)) { status = stat(cil_path, &sb); if (status == 0) { status = map_compressed_file(sh, cil_path, &contents); if (status < 0) { ERR(sh, "Error mapping file: %s", cil_path); return -1; } /* prefix with length to avoid collisions */ update_checksum_with_len(&context, contents.len); Sha256Update(&context, contents.data, contents.len); unmap_compressed_file(&contents); continue; } else if (errno != ENOENT) { ERR(sh, "Unable to access %s.", cil_path); return -1; //an error in the "stat" call } } status = semanage_compile_module(sh, &modinfos[i], &context); if (status < 0) return -1; } Sha256Finalise(&context, &hash); semanage_hash_to_checksum_string(hash.bytes, cil_checksum); return 0; } static int semanage_compare_checksum(semanage_handle_t *sh, const char *reference) { const char *path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_CHECKSUM); struct stat sb; int fd, retval; char *data; fd = open(path, O_RDONLY | O_CLOEXEC); if (fd == -1) { if (errno != ENOENT) { ERR(sh, "Unable to open %s.", path); return -1; } /* Checksum file not present - force a rebuild. */ return 1; } if (fstat(fd, &sb) == -1) { ERR(sh, "Unable to stat %s.", path); retval = -1; goto out_close; } if (sb.st_size != (off_t)CHECKSUM_CONTENT_SIZE) { /* Incompatible/invalid hash type - just force a rebuild. */ WARN(sh, "Module checksum invalid - forcing a rebuild."); retval = 1; goto out_close; } data = mmap(NULL, CHECKSUM_CONTENT_SIZE, PROT_READ, MAP_PRIVATE, fd, 0); if (data == MAP_FAILED) { ERR(sh, "Unable to mmap %s.", path); retval = -1; goto out_close; } retval = memcmp(data, reference, CHECKSUM_CONTENT_SIZE) != 0; munmap(data, sb.st_size); out_close: close(fd); return retval; } static int semanage_write_modules_checksum(semanage_handle_t *sh, const char *checksum) { const char *path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_CHECKSUM); return write_file(sh, path, checksum, CHECKSUM_CONTENT_SIZE); } /* Files that must exist in order to skip policy rebuild. */ static const int semanage_computed_files[] = { SEMANAGE_STORE_KERNEL, SEMANAGE_STORE_FC, SEMANAGE_STORE_SEUSERS, SEMANAGE_LINKED, SEMANAGE_SEUSERS_LINKED, SEMANAGE_USERS_EXTRA_LINKED }; /* Copies a file from src to dst. If dst already exists then * overwrite it. If source doesn't exist then return success. * Returns 0 on success, -1 on error. */ static int copy_file_if_exists(semanage_handle_t *sh, const char *src, const char *dst, mode_t mode){ int rc = semanage_copy_file(sh, src, dst, mode, false); return (rc < 0 && errno != ENOENT) ? rc : 0; } /********************* 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 *fc_buffer = NULL; size_t fc_buffer_len = 0; const char *ofilename = NULL; const char *path; int retval = -1, num_modinfos = 0, i; sepol_policydb_t *out = NULL; struct cil_db *cildb = NULL; semanage_module_info_t *modinfos = NULL; mode_t mask = umask(0077); struct stat sb; char modules_checksum[CHECKSUM_CONTENT_SIZE + 1 /* '\0' */]; struct extra_checksum_params extra; int do_rebuild, do_write_kernel, do_install; int fcontexts_modified, ports_modified, seusers_modified, disable_dontaudit, preserve_tunables, ibpkeys_modified, ibendports_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 *pusers_extra = semanage_user_extra_dbase_policy(sh); dbase_config_t *ports = semanage_port_dbase_local(sh); dbase_config_t *pports = semanage_port_dbase_policy(sh); dbase_config_t *ibpkeys = semanage_ibpkey_dbase_local(sh); dbase_config_t *pibpkeys = semanage_ibpkey_dbase_policy(sh); dbase_config_t *ibendports = semanage_ibendport_dbase_local(sh); dbase_config_t *pibendports = semanage_ibendport_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); dbase_config_t *pseusers = semanage_seuser_dbase_policy(sh); /* Modified flags that we need to use more than once. */ ports_modified = ports->dtable->is_modified(ports->dbase); ibpkeys_modified = ibpkeys->dtable->is_modified(ibpkeys->dbase); ibendports_modified = ibendports->dtable->is_modified(ibendports->dbase); seusers_modified = seusers->dtable->is_modified(seusers->dbase); fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase); /* 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; } /* Rebuild if explicitly requested or any module changes occurred. */ do_rebuild = sh->do_rebuild | sh->modules_modified; /* Create or remove the disable_dontaudit flag file. */ path = semanage_path(SEMANAGE_TMP, SEMANAGE_DISABLE_DONTAUDIT); if (stat(path, &sb) == 0) do_rebuild |= !(sepol_get_disable_dontaudit(sh->sepolh) == 1); else if (errno == ENOENT) { /* The file does not exist */ do_rebuild |= (sepol_get_disable_dontaudit(sh->sepolh) == 1); } else { ERR(sh, "Unable to access %s.", path); retval = -1; goto cleanup; } if (sepol_get_disable_dontaudit(sh->sepolh) == 1) { FILE *touch; touch = fopen(path, "we"); if (touch != NULL) { if (fclose(touch) != 0 && errno != EINTR) { 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 (stat(path, &sb) == 0) do_rebuild |= !(sepol_get_preserve_tunables(sh->sepolh) == 1); else if (errno == ENOENT) { /* The file does not exist */ do_rebuild |= (sepol_get_preserve_tunables(sh->sepolh) == 1); } else { ERR(sh, "Unable to access %s.", path); retval = -1; goto cleanup; } if (sepol_get_preserve_tunables(sh->sepolh) == 1) { FILE *touch; touch = fopen(path, "we"); if (touch != NULL) { if (fclose(touch) != 0 && errno != EINTR) { 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; } } /* * This is for systems that have already migrated with an older version * of semanage_migrate_store. The older version did not copy * policy.kern so the policy binary must be rebuilt here. * This also ensures that any linked files that are required * in order to skip re-linking are present; otherwise, we force * a rebuild. */ for (i = 0; !do_rebuild && i < (int)ARRAY_SIZE(semanage_computed_files); i++) { path = semanage_path(SEMANAGE_TMP, semanage_computed_files[i]); if (stat(path, &sb) != 0) { if (errno != ENOENT) { ERR(sh, "Unable to access %s.", path); retval = -1; goto cleanup; } do_rebuild = 1; break; } } if (do_rebuild || sh->check_ext_changes) { retval = semanage_get_active_modules(sh, &modinfos, &num_modinfos); if (retval < 0) { goto cleanup; } /* No modules - nothing to rebuild. */ if (num_modinfos == 0) { goto cleanup; } extra = (struct extra_checksum_params){ .disable_dontaudit = sepol_get_disable_dontaudit(sh->sepolh), .preserve_tunables = sepol_get_preserve_tunables(sh->sepolh), .target_platform = sh->conf->target_platform, .policyvers = sh->conf->policyvers, }; retval = semanage_compile_hll_modules(sh, modinfos, num_modinfos, &extra, modules_checksum); if (retval < 0) { ERR(sh, "Failed to compile hll files into cil files."); goto cleanup; } if (!do_rebuild && sh->check_ext_changes) { retval = semanage_compare_checksum(sh, modules_checksum); if (retval < 0) goto cleanup; do_rebuild = retval; } retval = semanage_write_modules_checksum(sh, modules_checksum); if (retval < 0) { ERR(sh, "Failed to write module checksum file."); goto cleanup; } } /* * If there were policy changes, or explicitly requested, or * any required files are missing, rebuild the policy. */ if (do_rebuild) { /* =================== Module expansion =============== */ retval = semanage_get_cil_paths(sh, modinfos, num_modinfos, &mod_filenames); if (retval < 0) goto cleanup; retval = semanage_verify_modules(sh, mod_filenames, num_modinfos); if (retval < 0) goto cleanup; cil_db_init(&cildb); disable_dontaudit = sepol_get_disable_dontaudit(sh->sepolh); preserve_tunables = sepol_get_preserve_tunables(sh->sepolh); cil_set_disable_dontaudit(cildb, disable_dontaudit); cil_set_disable_neverallow(cildb, !(sh->conf->expand_check)); cil_set_preserve_tunables(cildb, preserve_tunables); cil_set_target_platform(cildb, sh->conf->target_platform); cil_set_policy_version(cildb, sh->conf->policyvers); cil_set_multiple_decls(cildb, sh->conf->multiple_decls); if (sh->conf->handle_unknown != -1) { retval = cil_set_handle_unknown(cildb, sh->conf->handle_unknown); if (retval < 0) goto cleanup; } retval = semanage_load_files(sh, cildb, mod_filenames, num_modinfos); if (retval < 0) { goto cleanup; } retval = cil_compile(cildb); if (retval < 0) goto cleanup; retval = cil_build_policydb(cildb, &out); if (retval < 0) goto cleanup; /* File Contexts */ retval = cil_filecons_to_string(cildb, &fc_buffer, &fc_buffer_len); if (retval < 0) goto cleanup; /* Write the contexts (including template contexts) to a single file. */ ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL); if (ofilename == NULL) { retval = -1; goto cleanup; } retval = write_file(sh, ofilename, fc_buffer, fc_buffer_len); 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; /* remove FC_TMPL now that it is now longer needed */ unlink(semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL)); pfcontexts->dtable->drop_cache(pfcontexts->dbase); /* SEUsers */ retval = semanage_direct_update_seuser(sh, cildb); if (retval < 0) goto cleanup; /* User Extra */ retval = semanage_direct_update_user_extra(sh, cildb); if (retval < 0) goto cleanup; cil_db_destroy(&cildb); /* Remove redundancies in binary policy if requested. */ if (sh->conf->optimize_policy) { retval = sepol_policydb_optimize(out); if (retval < 0) goto cleanup; } /* Write the linked policy before merging local changes. */ retval = semanage_write_policydb(sh, out, SEMANAGE_LINKED); if (retval < 0) goto cleanup; } else { /* Load the existing linked policy, w/o local changes */ retval = sepol_policydb_create(&out); if (retval < 0) goto cleanup; retval = semanage_read_policydb(sh, out, SEMANAGE_LINKED); if (retval < 0) goto cleanup; path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED); if (stat(path, &sb) == 0) { retval = semanage_copy_file(sh, path, semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS), 0, false); if (retval < 0) goto cleanup; pseusers->dtable->drop_cache(pseusers->dbase); } else if (errno == ENOENT) { /* The file does not exist */ pseusers->dtable->clear(sh, pseusers->dbase); } else { ERR(sh, "Unable to access %s.", path); retval = -1; goto cleanup; } path = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED); if (stat(path, &sb) == 0) { retval = semanage_copy_file(sh, path, semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA), 0, false); if (retval < 0) goto cleanup; pusers_extra->dtable->drop_cache(pusers_extra->dbase); } else if (errno == ENOENT) { /* The file does not exist */ pusers_extra->dtable->clear(sh, pusers_extra->dbase); } else { ERR(sh, "Unable to access %s.", path); retval = -1; goto cleanup; } } /* * Determine what else needs to be done. * We need to write the kernel policy if we are rebuilding * or if any other policy component that lives in the kernel * policy has been modified. We also want to force it when * check_ext_changes was specified as the various dbases may have * changes as well. * We need to install the policy files if any of the managed files * that live under /etc/selinux (kernel policy, seusers, file contexts) * will be modified. */ do_write_kernel = do_rebuild | sh->check_ext_changes | ports_modified | ibpkeys_modified | ibendports_modified | bools->dtable->is_modified(bools->dbase) | ifaces->dtable->is_modified(ifaces->dbase) | nodes->dtable->is_modified(nodes->dbase) | users->dtable->is_modified(users_base->dbase); do_install = do_write_kernel | seusers_modified | fcontexts_modified; /* Attach our databases to the policydb we just created or loaded. */ 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 *) pibpkeys->dbase, out); dbase_policydb_attach((dbase_policydb_t *) pibendports->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); /* Merge local changes */ retval = semanage_base_merge_components(sh); if (retval < 0) goto cleanup; if (do_write_kernel) { /* Write new kernel policy. */ retval = semanage_write_policydb(sh, out, SEMANAGE_STORE_KERNEL); if (retval < 0) goto cleanup; /* Run the kernel policy verifier, if any. */ retval = semanage_verify_kernel(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 (do_rebuild || fcontexts_modified) { retval = semanage_fcontext_validate_local(sh, out); if (retval < 0) goto cleanup; } /* Validate local seusers against policy */ if (do_rebuild || seusers_modified) { retval = semanage_seuser_validate_local(sh, out); if (retval < 0) goto cleanup; } /* Validate local ports for overlap */ if (do_rebuild || ports_modified) { retval = semanage_port_validate_local(sh); if (retval < 0) goto cleanup; } /* Validate local ibpkeys for overlap */ if (do_rebuild || ibpkeys_modified) { retval = semanage_ibpkey_validate_local(sh); if (retval < 0) goto cleanup; } /* Validate local ibendports */ if (do_rebuild || ibendports_modified) { retval = semanage_ibendport_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; retval = semanage_copy_file(sh, semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL), sh->conf->file_mode, false); if (retval < 0) { goto cleanup; } retval = copy_file_if_exists(sh, semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL), semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL), sh->conf->file_mode); if (retval < 0) { goto cleanup; } retval = copy_file_if_exists(sh, semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC), semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC), sh->conf->file_mode); if (retval < 0) { goto cleanup; } retval = copy_file_if_exists(sh, semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS), semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS), sh->conf->file_mode); 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){ if ((retval = semanage_genhomedircon(sh, out, sh->conf->usepasswd, sh->conf->ignoredirs)) != 0) { ERR(sh, "semanage_genhomedircon returned error code %d.", retval); goto cleanup; } /* file_contexts.homedirs was created in SEMANAGE_TMP store */ retval = semanage_copy_file( sh, semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS), semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS), sh->conf->file_mode, false); if (retval < 0) { 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 (do_install) retval = semanage_install_sandbox(sh); cleanup: for (i = 0; i < num_modinfos; i++) { semanage_module_info_destroy(sh, &modinfos[i]); } free(modinfos); for (i = 0; mod_filenames != NULL && i < num_modinfos; i++) { free(mod_filenames[i]); } /* 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 *) pibpkeys->dbase); dbase_policydb_detach((dbase_policydb_t *) pibendports->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); cil_db_destroy(&cildb); free(fc_buffer); /* Set commit_err so other functions can detect any errors. Note that * retval > 0 will be the commit number. */ if (retval < 0) sh->commit_err = retval; if (semanage_remove_tmps(sh) != 0) retval = -1; semanage_release_trans_lock(sh); umask(mask); 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, const char *module_name, const char *lang_ext) { int status = 0; int ret = 0; semanage_module_info_t modinfo; ret = semanage_module_info_init(sh, &modinfo); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_set_name(sh, &modinfo, module_name); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_set_lang_ext(sh, &modinfo, lang_ext); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_set_enabled(sh, &modinfo, -1); if (ret != 0) { status = -1; goto cleanup; } status = semanage_direct_install_info(sh, &modinfo, data, data_len); cleanup: semanage_module_info_destroy(sh, &modinfo); return status; } /* 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 *path = NULL; const char *filename; const char *lang_ext = NULL; char *module_name = NULL; char *separator; char *version = NULL; struct file_contents contents = {}; retval = map_compressed_file(sh, install_filename, &contents); if (retval < 0) { ERR(sh, "Unable to read file %s.", install_filename); goto cleanup; } path = strdup(install_filename); if (path == NULL) { ERR(sh, "No memory available for strdup."); retval = -1; goto cleanup; } filename = basename(path); if (contents.compressed) { separator = strrchr(filename, '.'); if (separator == NULL) { ERR(sh, "Compressed module does not have a valid extension."); retval = -1; goto cleanup; } *separator = '\0'; lang_ext = separator + 1; } separator = strrchr(filename, '.'); if (separator == NULL) { if (lang_ext == NULL) { ERR(sh, "Module does not have a valid extension."); retval = -1; goto cleanup; } } else { *separator = '\0'; lang_ext = separator + 1; } if (strcmp(lang_ext, "pp") == 0) { retval = parse_module_headers(sh, contents.data, contents.len, &module_name, &version); free(version); if (retval != 0) goto cleanup; } if (module_name == NULL) { module_name = strdup(filename); if (module_name == NULL) { ERR(sh, "No memory available for module_name."); retval = -1; goto cleanup; } } else if (strcmp(module_name, filename) != 0) { ERR(sh, "Warning: SELinux userspace will refer to the module from %s as %s rather than %s.", install_filename, module_name, filename); } retval = semanage_direct_install(sh, contents.data, contents.len, module_name, lang_ext); cleanup: unmap_compressed_file(&contents); free(module_name); free(path); return retval; } static int semanage_direct_extract(semanage_handle_t * sh, semanage_module_key_t *modkey, int extract_cil, void **mapped_data, size_t *data_len, semanage_module_info_t **modinfo) { char module_path[PATH_MAX]; char input_file[PATH_MAX]; enum semanage_module_path_type file_type; int rc = -1; semanage_module_info_t *_modinfo = NULL; struct stat sb; struct file_contents contents = {}; /* get path of module */ rc = semanage_module_get_path( sh, (const semanage_module_info_t *)modkey, SEMANAGE_MODULE_PATH_NAME, module_path, sizeof(module_path)); if (rc != 0) { goto cleanup; } if (stat(module_path, &sb) != 0) { ERR(sh, "Unable to access %s.", module_path); rc = -1; goto cleanup; } rc = semanage_module_get_module_info(sh, modkey, &_modinfo); if (rc != 0) { goto cleanup; } if (extract_cil || strcmp(_modinfo->lang_ext, "cil") == 0) { file_type = SEMANAGE_MODULE_PATH_CIL; } else { file_type = SEMANAGE_MODULE_PATH_HLL; } /* get path of what to extract */ rc = semanage_module_get_path( sh, _modinfo, file_type, input_file, sizeof(input_file)); if (rc != 0) { goto cleanup; } if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && stat(input_file, &sb) != 0) { if (errno != ENOENT) { ERR(sh, "Unable to access %s.", input_file); rc = -1; goto cleanup; } rc = semanage_compile_module(sh, _modinfo, NULL); if (rc < 0) { goto cleanup; } } rc = map_compressed_file(sh, input_file, &contents); if (rc < 0) { ERR(sh, "Error mapping file: %s", input_file); goto cleanup; } /* The API promises an mmap'ed pointer */ if (contents.compressed) { *mapped_data = mmap(NULL, contents.len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); if (*mapped_data == MAP_FAILED) { ERR(sh, "Unable to map memory"); rc = -1; goto cleanup; } memcpy(*mapped_data, contents.data, contents.len); free(contents.data); } else { *mapped_data = contents.data; } *modinfo = _modinfo; *data_len = contents.len; cleanup: if (rc != 0) { unmap_compressed_file(&contents); semanage_module_info_destroy(sh, _modinfo); free(_modinfo); } return rc; } /* 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) { int status = 0; int ret = 0; semanage_module_key_t modkey; ret = semanage_module_key_init(sh, &modkey); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_key_set_priority(sh, &modkey, sh->priority); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_key_set_name(sh, &modkey, module_name); if (ret != 0) { status = -1; goto cleanup; } status = semanage_direct_remove_key(sh, &modkey); cleanup: semanage_module_key_destroy(sh, &modkey); return status; } /* 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) { int i, retval = -1; *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_active_modules(sh, modinfo, num_modules) == -1) { goto cleanup; } retval = semanage_direct_get_serial(sh); cleanup: if (retval < 0) { for (i = 0; i < *num_modules; i++) { semanage_module_info_destroy(sh, &(*modinfo[i])); modinfo[i] = NULL; } free(*modinfo); *modinfo = NULL; } if (!sh->is_in_transaction) { semanage_release_active_lock(sh); } return retval; } static int semanage_direct_get_enabled(semanage_handle_t *sh, const semanage_module_key_t *modkey, int *enabled) { assert(sh); assert(modkey); assert(enabled); int status = 0; int ret = 0; char path[PATH_MAX]; struct stat sb; semanage_module_info_t *modinfo = NULL; /* get module info */ ret = semanage_module_get_module_info( sh, modkey, &modinfo); if (ret != 0) { status = -1; goto cleanup; } /* get disabled file path */ ret = semanage_module_get_path( sh, modinfo, SEMANAGE_MODULE_PATH_DISABLED, path, sizeof(path)); if (ret != 0) { status = -1; goto cleanup; } if (stat(path, &sb) < 0) { if (errno != ENOENT) { ERR(sh, "Unable to access %s.", path); status = -1; goto cleanup; } *enabled = 1; } else { *enabled = 0; } cleanup: semanage_module_info_destroy(sh, modinfo); free(modinfo); return status; } static int semanage_direct_set_enabled(semanage_handle_t *sh, const semanage_module_key_t *modkey, int enabled) { assert(sh); assert(modkey); int status = 0; int ret = 0; char fn[PATH_MAX]; const char *path = NULL; FILE *fp = NULL; semanage_module_info_t *modinfo = NULL; mode_t mask; /* check transaction */ if (!sh->is_in_transaction) { if (semanage_begin_transaction(sh) < 0) { status = -1; goto cleanup; } } /* validate name */ ret = semanage_module_validate_name(modkey->name); if (ret != 0) { errno = 0; ERR(sh, "Name %s is invalid.", modkey->name); status = -1; goto cleanup; } /* validate enabled */ ret = semanage_module_validate_enabled(enabled); if (ret != 0) { errno = 0; ERR(sh, "Enabled status %d is invalid.", enabled); status = -1; goto cleanup; } /* check for disabled path, create if missing */ path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_DISABLED); ret = semanage_mkdir(sh, path); if (ret != 0) { status = -1; goto cleanup; } /* get module info */ ret = semanage_module_get_module_info( sh, modkey, &modinfo); if (ret != 0) { status = -1; goto cleanup; } /* get module disabled file */ ret = semanage_module_get_path( sh, modinfo, SEMANAGE_MODULE_PATH_DISABLED, fn, sizeof(fn)); if (ret != 0) { status = -1; goto cleanup; } switch (enabled) { case 0: /* disable the module */ mask = umask(0077); fp = fopen(fn, "we"); umask(mask); if (fp == NULL) { ERR(sh, "Unable to disable module %s", modkey->name); status = -1; goto cleanup; } ret = fclose(fp); fp = NULL; if (ret != 0 && errno != EINTR) { ERR(sh, "Unable to close disabled file for module %s", modkey->name); status = -1; goto cleanup; } break; case 1: /* enable the module */ if (unlink(fn) < 0) { if (errno != ENOENT) { ERR(sh, "Unable to enable module %s", modkey->name); status = -1; goto cleanup; } else { /* module already enabled */ errno = 0; } } break; case -1: /* warn about ignored setting to default */ WARN(sh, "Setting module %s to 'default' state has no effect", modkey->name); break; } cleanup: semanage_module_info_destroy(sh, modinfo); free(modinfo); if (fp != NULL) fclose(fp); return status; } int semanage_direct_access_check(semanage_handle_t * sh) { if (semanage_check_init(sh, sh->conf->store_root_path)) 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, SEMANAGE_STORE_KERNEL); if (retval < 0) goto cleanup; retval = sepol_policydb_mls_enabled(p); cleanup: sepol_policydb_free(p); return retval; } static int semanage_direct_get_module_info(semanage_handle_t *sh, const semanage_module_key_t *modkey, semanage_module_info_t **modinfo) { assert(sh); assert(modkey); assert(modinfo); int status = 0; int ret = 0; char fn[PATH_MAX]; FILE *fp = NULL; size_t size = 0; struct stat sb; char *tmp = NULL; int i = 0; semanage_module_info_t *modinfos = NULL; int modinfos_len = 0; const semanage_module_info_t *highest = NULL; /* check module name */ ret = semanage_module_validate_name(modkey->name); if (ret < 0) { errno = 0; ERR(sh, "Name %s is invalid.", modkey->name); status = -1; goto cleanup; } /* if priority == 0, then find the highest priority available */ if (modkey->priority == 0) { ret = semanage_direct_list_all(sh, &modinfos, &modinfos_len); if (ret != 0) { status = -1; goto cleanup; } for (i = 0; i < modinfos_len; i++) { ret = strcmp(modinfos[i].name, modkey->name); if (ret == 0) { highest = &modinfos[i]; break; } } if (highest == NULL) { status = -1; goto cleanup; } ret = semanage_module_info_create(sh, modinfo); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_clone(sh, highest, *modinfo); if (ret != 0) { status = -1; } /* skip to cleanup, module was found */ goto cleanup; } /* check module priority */ ret = semanage_module_validate_priority(modkey->priority); if (ret != 0) { errno = 0; ERR(sh, "Priority %d is invalid.", modkey->priority); status = -1; goto cleanup; } /* copy in key values */ ret = semanage_module_info_create(sh, modinfo); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_set_priority(sh, *modinfo, modkey->priority); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_set_name(sh, *modinfo, modkey->name); if (ret != 0) { status = -1; goto cleanup; } /* lookup module ext */ ret = semanage_module_get_path(sh, *modinfo, SEMANAGE_MODULE_PATH_LANG_EXT, fn, sizeof(fn)); if (ret != 0) { status = -1; goto cleanup; } fp = fopen(fn, "re"); if (fp == NULL) { ERR(sh, "Unable to open %s module lang ext file at %s.", (*modinfo)->name, fn); status = -1; goto cleanup; } /* set module ext */ if (getline(&tmp, &size, fp) < 0) { ERR(sh, "Unable to read %s module lang ext file.", (*modinfo)->name); status = -1; goto cleanup; } ret = semanage_module_info_set_lang_ext(sh, *modinfo, tmp); if (ret != 0) { status = -1; goto cleanup; } free(tmp); tmp = NULL; if (fclose(fp) != 0 && errno != EINTR) { fp = NULL; ERR(sh, "Unable to close %s module lang ext file.", (*modinfo)->name); status = -1; goto cleanup; } fp = NULL; /* lookup enabled/disabled status */ ret = semanage_module_get_path(sh, *modinfo, SEMANAGE_MODULE_PATH_DISABLED, fn, sizeof(fn)); if (ret != 0) { status = -1; goto cleanup; } /* set enabled/disabled status */ if (stat(fn, &sb) < 0) { if (errno != ENOENT) { ERR(sh, "Unable to access %s.", fn); status = -1; goto cleanup; } ret = semanage_module_info_set_enabled(sh, *modinfo, 1); if (ret != 0) { status = -1; goto cleanup; } } else { ret = semanage_module_info_set_enabled(sh, *modinfo, 0); if (ret != 0) { status = -1; goto cleanup; } } cleanup: free(tmp); if (modinfos != NULL) { for (i = 0; i < modinfos_len; i++) { semanage_module_info_destroy(sh, &modinfos[i]); } free(modinfos); } if (fp != NULL) fclose(fp); return status; } static int semanage_direct_set_module_info(semanage_handle_t *sh, const semanage_module_info_t *modinfo) { int status = 0; int ret = 0; char fn[PATH_MAX]; const char *path = NULL; int enabled = 0; semanage_module_info_t *modinfo_tmp = NULL; semanage_module_key_t modkey; ret = semanage_module_key_init(sh, &modkey); if (ret != 0) { status = -1; goto cleanup; } /* check transaction */ if (!sh->is_in_transaction) { if (semanage_begin_transaction(sh) < 0) { status = -1; goto cleanup; } } /* validate module */ ret = semanage_module_info_validate(modinfo); if (ret != 0) { status = -1; goto cleanup; } sh->modules_modified = 1; /* check for modules path, create if missing */ path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES); ret = semanage_mkdir(sh, path); if (ret != 0) { status = -1; goto cleanup; } /* write priority */ ret = semanage_module_get_path(sh, modinfo, SEMANAGE_MODULE_PATH_PRIORITY, fn, sizeof(fn)); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_mkdir(sh, fn); if (ret != 0) { status = -1; goto cleanup; } /* write name */ ret = semanage_module_get_path(sh, modinfo, SEMANAGE_MODULE_PATH_NAME, fn, sizeof(fn)); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_mkdir(sh, fn); if (ret != 0) { status = -1; goto cleanup; } /* write ext */ ret = semanage_direct_write_langext(sh, modinfo->lang_ext, modinfo); if (ret != 0) { status = -1; goto cleanup; } /* write enabled/disabled status */ /* check for disabled path, create if missing */ path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_DISABLED); ret = semanage_mkdir(sh, path); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_get_path(sh, modinfo, SEMANAGE_MODULE_PATH_DISABLED, fn, sizeof(fn)); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_key_set_name(sh, &modkey, modinfo->name); if (ret != 0) { status = -1; goto cleanup; } if (modinfo->enabled == -1) { /* default to enabled */ enabled = 1; /* check if a module is already installed */ ret = semanage_module_get_module_info(sh, &modkey, &modinfo_tmp); if (ret == 0) { /* set enabled status to current one */ enabled = modinfo_tmp->enabled; } } else { enabled = modinfo->enabled; } ret = semanage_module_set_enabled(sh, &modkey, enabled); if (ret != 0) { status = -1; goto cleanup; } cleanup: semanage_module_key_destroy(sh, &modkey); semanage_module_info_destroy(sh, modinfo_tmp); free(modinfo_tmp); return status; } static int semanage_priorities_filename_select(const struct dirent *d) { if (d->d_name[0] == '.' || strcmp(d->d_name, "disabled") == 0) return 0; return 1; } static int semanage_modules_filename_select(const struct dirent *d) { if (d->d_name[0] == '.') return 0; return 1; } static int semanage_direct_list_all(semanage_handle_t *sh, semanage_module_info_t **modinfos, int *modinfos_len) { assert(sh); assert(modinfos); assert(modinfos_len); int status = 0; int ret = 0; int i = 0; int j = 0; *modinfos = NULL; *modinfos_len = 0; void *tmp = NULL; const char *toplevel = NULL; struct dirent **priorities = NULL; int priorities_len = 0; char priority_path[PATH_MAX]; struct dirent **modules = NULL; int modules_len = 0; uint16_t priority = 0; semanage_module_info_t *modinfo_tmp = NULL; semanage_module_info_t modinfo; ret = semanage_module_info_init(sh, &modinfo); if (ret != 0) { status = -1; goto cleanup; } if (sh->is_in_transaction) { toplevel = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES); } else { toplevel = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_MODULES); } /* find priorities */ priorities_len = scandir(toplevel, &priorities, semanage_priorities_filename_select, versionsort); if (priorities_len == -1) { ERR(sh, "Error while scanning directory %s.", toplevel); status = -1; goto cleanup; } /* for each priority directory */ /* loop through in reverse so that highest priority is first */ for (i = priorities_len - 1; i >= 0; i--) { /* convert priority string to uint16_t */ ret = semanage_string_to_priority(priorities[i]->d_name, &priority); if (ret != 0) { status = -1; goto cleanup; } /* set our priority */ ret = semanage_module_info_set_priority(sh, &modinfo, priority); if (ret != 0) { status = -1; goto cleanup; } /* get the priority path */ ret = semanage_module_get_path(sh, &modinfo, SEMANAGE_MODULE_PATH_PRIORITY, priority_path, sizeof(priority_path)); if (ret != 0) { status = -1; goto cleanup; } /* cleanup old modules */ if (modules != NULL) { for (j = 0; j < modules_len; j++) { free(modules[j]); modules[j] = NULL; } free(modules); modules = NULL; modules_len = 0; } /* find modules at this priority */ modules_len = scandir(priority_path, &modules, semanage_modules_filename_select, versionsort); if (modules_len == -1) { ERR(sh, "Error while scanning directory %s.", priority_path); status = -1; goto cleanup; } if (modules_len == 0) continue; /* add space for modules */ tmp = realloc(*modinfos, sizeof(semanage_module_info_t) * (*modinfos_len + modules_len)); if (tmp == NULL) { ERR(sh, "Error allocating memory for module array."); status = -1; goto cleanup; } *modinfos = tmp; /* for each module directory */ for(j = 0; j < modules_len; j++) { /* set module name */ ret = semanage_module_info_set_name( sh, &modinfo, modules[j]->d_name); if (ret != 0) { status = -1; goto cleanup; } /* get module values */ ret = semanage_direct_get_module_info( sh, (const semanage_module_key_t *) (&modinfo), &modinfo_tmp); if (ret != 0) { status = -1; goto cleanup; } /* copy into array */ ret = semanage_module_info_init( sh, &((*modinfos)[*modinfos_len])); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_clone( sh, modinfo_tmp, &((*modinfos)[*modinfos_len])); if (ret != 0) { status = -1; goto cleanup; } semanage_module_info_destroy(sh, modinfo_tmp); free(modinfo_tmp); modinfo_tmp = NULL; *modinfos_len += 1; } } cleanup: semanage_module_info_destroy(sh, &modinfo); if (priorities != NULL) { for (i = 0; i < priorities_len; i++) { free(priorities[i]); } free(priorities); } if (modules != NULL) { for (i = 0; i < modules_len; i++) { free(modules[i]); } free(modules); } semanage_module_info_destroy(sh, modinfo_tmp); free(modinfo_tmp); modinfo_tmp = NULL; if (status != 0) { if (modinfos != NULL) { for (i = 0; i < *modinfos_len; i++) { semanage_module_info_destroy( sh, &(*modinfos)[i]); } free(*modinfos); *modinfos = NULL; *modinfos_len = 0; } } return status; } static int semanage_direct_install_info(semanage_handle_t *sh, const semanage_module_info_t *modinfo, char *data, size_t data_len) { assert(sh); assert(modinfo); assert(data); int status = 0; int ret = 0; int type; char path[PATH_MAX]; mode_t mask = umask(0077); semanage_module_info_t *higher_info = NULL; semanage_module_key_t higher_key; ret = semanage_module_key_init(sh, &higher_key); if (ret != 0) { status = -1; goto cleanup; } /* validate module info */ ret = semanage_module_info_validate(modinfo); if (ret != 0) { ERR(sh, "%s failed module validation.", modinfo->name); status = -2; goto cleanup; } /* Check for higher priority module and warn if there is one as * it will override the module currently being installed. */ ret = semanage_module_key_set_name(sh, &higher_key, modinfo->name); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_direct_get_module_info(sh, &higher_key, &higher_info); if (ret == 0) { if (higher_info->priority > modinfo->priority) { errno = 0; WARN(sh, "A higher priority %s module exists at priority %d and will override the module currently being installed at priority %d.", modinfo->name, higher_info->priority, modinfo->priority); } else if (higher_info->priority < modinfo->priority) { errno = 0; INFO(sh, "Overriding %s module at lower priority %d with module at priority %d.", modinfo->name, higher_info->priority, modinfo->priority); } if (higher_info->enabled == 0 && modinfo->enabled == -1) { errno = 0; WARN(sh, "%s module will be disabled after install as there is a disabled instance of this module present in the system.", modinfo->name); } } /* set module meta data */ ret = semanage_direct_set_module_info(sh, modinfo); if (ret != 0) { status = -2; goto cleanup; } /* install module source file */ if (!strcasecmp(modinfo->lang_ext, "cil")) { type = SEMANAGE_MODULE_PATH_CIL; } else { type = SEMANAGE_MODULE_PATH_HLL; } ret = semanage_module_get_path( sh, modinfo, type, path, sizeof(path)); if (ret != 0) { status = -3; goto cleanup; } ret = write_compressed_file(sh, path, data, data_len); if (ret < 0) { ERR(sh, "Error while writing to %s.", path); status = -3; goto cleanup; } /* if this is an HLL, delete the CIL cache if it exists so it will get recompiled */ if (type == SEMANAGE_MODULE_PATH_HLL) { ret = semanage_module_get_path( sh, modinfo, SEMANAGE_MODULE_PATH_CIL, path, sizeof(path)); if (ret != 0) { status = -3; goto cleanup; } ret = unlink(path); if (ret != 0 && errno != ENOENT) { ERR(sh, "Error while removing cached CIL file %s.", path); status = -3; goto cleanup; } } cleanup: semanage_module_key_destroy(sh, &higher_key); semanage_module_info_destroy(sh, higher_info); free(higher_info); umask(mask); return status; } static int semanage_direct_remove_key(semanage_handle_t *sh, const semanage_module_key_t *modkey) { assert(sh); assert(modkey); int status = 0; int ret = 0; char path[PATH_MAX]; semanage_module_info_t *modinfo = NULL; semanage_module_key_t modkey_tmp; ret = semanage_module_key_init(sh, &modkey_tmp); if (ret != 0) { status = -1; goto cleanup; } /* validate module key */ ret = semanage_module_validate_priority(modkey->priority); if (ret != 0) { errno = 0; ERR(sh, "Priority %d is invalid.", modkey->priority); status = -1; goto cleanup; } ret = semanage_module_validate_name(modkey->name); if (ret != 0) { errno = 0; ERR(sh, "Name %s is invalid.", modkey->name); status = -1; goto cleanup; } ret = semanage_module_key_set_name(sh, &modkey_tmp, modkey->name); if (ret != 0) { status = -1; goto cleanup; } /* get module path */ ret = semanage_module_get_path( sh, (const semanage_module_info_t *)modkey, SEMANAGE_MODULE_PATH_NAME, path, sizeof(path)); if (ret != 0) { status = -2; goto cleanup; } /* remove directory */ ret = semanage_remove_directory(path); if (ret != 0) { ERR(sh, "Unable to remove module %s at priority %d.", modkey->name, modkey->priority); status = -2; goto cleanup; } /* check if its the last module at any priority */ ret = semanage_module_get_module_info(sh, &modkey_tmp, &modinfo); if (ret != 0) { /* info that no other module will override */ errno = 0; INFO(sh, "Removing last %s module (no other %s module exists at another priority).", modkey->name, modkey->name); /* remove disabled status file */ ret = semanage_module_get_path( sh, (const semanage_module_info_t *)modkey, SEMANAGE_MODULE_PATH_DISABLED, path, sizeof(path)); if (ret != 0) { status = -1; goto cleanup; } ret = unlink(path); if (ret != 0 && errno != ENOENT) { status = -1; goto cleanup; } } else { /* if a lower priority module is going to become active */ if (modkey->priority > modinfo->priority) { /* inform what the new active module will be */ errno = 0; INFO(sh, "%s module at priority %d is now active.", modinfo->name, modinfo->priority); } } cleanup: semanage_module_key_destroy(sh, &modkey_tmp); semanage_module_info_destroy(sh, modinfo); free(modinfo); return status; } libsemanage-3.8.1/src/direct_api.h000066400000000000000000000025101476211737200170450ustar00rootroot00000000000000/* 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); #endif libsemanage-3.8.1/src/exception.sh000066400000000000000000000007621476211737200171320ustar00rootroot00000000000000function except() { echo " %exception $1 { \$action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } }" } if ! ${CC:-gcc} -x c -c -I../include -o temp.o - -aux-info temp.aux < ../include/semanage/semanage.h then # clang does not support -aux-info so fall back to gcc gcc -x c -c -I../include -o temp.o - -aux-info temp.aux < ../include/semanage/semanage.h fi for i in `awk '/extern int/ { print $6 }' temp.aux`; do except $i ; done rm -f -- temp.aux temp.o libsemanage-3.8.1/src/fcontext_internal.h000066400000000000000000000013141476211737200204710ustar00rootroot00000000000000#ifndef _SEMANAGE_FCONTEXT_INTERNAL_H_ #define _SEMANAGE_FCONTEXT_INTERNAL_H_ #include #include #include #include #include "database.h" #include "handle.h" /* FCONTEXT RECORD: method table */ extern const record_table_t SEMANAGE_FCONTEXT_RTABLE; extern int fcontext_file_dbase_init(semanage_handle_t * handle, const char *path_ro, const char *path_rw, dbase_config_t * dconfig); extern void fcontext_file_dbase_release(dbase_config_t * dconfig); extern int semanage_fcontext_validate_local(semanage_handle_t * handle, const sepol_policydb_t * policydb); #endif libsemanage-3.8.1/src/fcontext_record.c000066400000000000000000000140271476211737200201330ustar00rootroot00000000000000struct 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 "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; } 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; } void semanage_fcontext_key_free(semanage_fcontext_key_t * key) { free(key->expr); free(key); } 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; } } 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; } } static int semanage_fcontext_compare2_qsort(const void *p1, const void *p2) { const semanage_fcontext_t *const *fcontext1 = p1; const semanage_fcontext_t *const *fcontext2 = p2; return semanage_fcontext_compare2(*fcontext1, *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; } /* Regexp */ const char *semanage_fcontext_get_expr(const semanage_fcontext_t * fcontext) { return fcontext->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; } /* Type */ int semanage_fcontext_get_type(const semanage_fcontext_t * fcontext) { return fcontext->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 "????"; } } void semanage_fcontext_set_type(semanage_fcontext_t * fcontext, int type) { fcontext->type = type; } /* Context */ semanage_context_t *semanage_fcontext_get_con(const semanage_fcontext_t * fcontext) { return fcontext->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; } /* 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; } /* Destroy */ void semanage_fcontext_free(semanage_fcontext_t * fcontext) { if (!fcontext) return; free(fcontext->expr); semanage_context_free(fcontext->con); free(fcontext); } /* Record base functions */ const 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-3.8.1/src/fcontexts_file.c000066400000000000000000000107441476211737200177610ustar00rootroot00000000000000/* 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 "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, const 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) < 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) < 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) < 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 */ static const 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 *path_ro, const char *path_rw, dbase_config_t * dconfig) { if (dbase_file_init(handle, path_ro, path_rw, &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-3.8.1/src/fcontexts_local.c000066400000000000000000000066021476211737200201320ustar00rootroot00000000000000/* 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 "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); } 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 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-3.8.1/src/fcontexts_policy.c000066400000000000000000000034131476211737200203340ustar00rootroot00000000000000/* 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); } int semanage_fcontext_list_homedirs(semanage_handle_t * handle, semanage_fcontext_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_fcontext_dbase_homedirs(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-3.8.1/src/genhomedircon.c000066400000000000000000001034611476211737200175650ustar00rootroot00000000000000/* 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 "fcontext_internal.h" #include "semanage_store.h" #include "seuser_internal.h" #include "user_internal.h" #include "debug.h" #include "utilities.h" #include "genhomedircon.h" #include #include #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" /* these are legacy */ #define TEMPLATE_USER "USER" #define TEMPLATE_ROLE "ROLE" /* new names */ #define TEMPLATE_USERNAME "%{USERNAME}" #define TEMPLATE_USERID "%{USERID}" #define FALLBACK_SENAME "user_u" #define FALLBACK_PREFIX "user" #define FALLBACK_LEVEL "s0" #define FALLBACK_NAME "[^/]+" #define FALLBACK_UIDGID "[0-9]+" #define DEFAULT_LOGIN "__default__" #define CONTEXT_NONE "<>" typedef struct user_entry { char *name; char *uid; char *gid; char *sename; char *prefix; char *home; char *level; char *login; char *homedir_role; struct user_entry *next; } genhomedircon_user_entry_t; typedef struct { const char *fcfilepath; int usepasswd; const char *homedir_template_path; genhomedircon_user_entry_t *fallback; semanage_handle_t *h_semanage; sepol_policydb_t *policydb; } genhomedircon_settings_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; static 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, *saveptr = NULL; ignoredir_t *ptr = NULL; tok = strtok_r(ignoredirs, ";", &saveptr); while(tok) { ptr = calloc(1, sizeof(ignoredir_t)); if (!ptr) goto err; ptr->dir = strdup(tok); if (!ptr->dir) goto err; ptr->next = ignore_head; ignore_head = ptr; tok = strtok_r(NULL, ";", &saveptr); } return 0; err: free(ptr); ignore_free(); return -1; } static int ignore(const char *homedir) { const ignoredir_t *ptr = ignore_head; while (ptr) { if (strcmp(ptr->dir, homedir) == 0) { return 1; } ptr = ptr->next; } return 0; } static int prefix_is_homedir_role(const semanage_user_t *user, const char *prefix) { return strcmp(OBJECT_R, prefix) == 0 || semanage_user_has_role(user, prefix); } static semanage_list_t *default_shell_list(void) { semanage_list_t *list = NULL; if (semanage_list_push(&list, "/bin/csh") || semanage_list_push(&list, "/usr/bin/csh") || semanage_list_push(&list, "/bin/tcsh") || semanage_list_push(&list, "/usr/bin/tcsh") || semanage_list_push(&list, "/bin/ksh") || semanage_list_push(&list, "/usr/bin/ksh") || semanage_list_push(&list, "/bin/bsh") || semanage_list_push(&list, "/usr/bin/bsh") || semanage_list_push(&list, "/bin/ash") || semanage_list_push(&list, "/usr/bin/ash") || semanage_list_push(&list, "/bin/pdksh") || semanage_list_push(&list, "/usr/bin/pdksh") || semanage_list_push(&list, "/bin/zsh") || semanage_list_push(&list, "/usr/bin/zsh") || semanage_list_push(&list, "/bin/sh") || semanage_list_push(&list, "/usr/bin/sh") || semanage_list_push(&list, "/bin/bash") || semanage_list_push(&list, "/usr/bin/bash")) goto fail; return list; fail: semanage_list_destroy(&list); return NULL; } static bool is_nologin_shell(const char *path) { return strcmp(path, PATH_NOLOGIN_SHELL) == 0 || strcmp(path, "/usr" PATH_NOLOGIN_SHELL) == 0; } 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, "re"); if (!shells) return default_shell_list(); while ((len = getline(&temp, &buff_len, shells)) > 0) { if (temp[len-1] == '\n') temp[len-1] = 0; if (is_nologin_shell(temp)) continue; if (semanage_list_push(&list, temp)) { free(temp); semanage_list_destroy(&list); fclose(shells); return NULL; } } free(temp); fclose(shells); 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; char *expr = NULL; regex_t re; int type, retval = -1; size_t len; /* Only match ALL or DIR */ type = semanage_fcontext_get_type(fcontext); if (type != SEMANAGE_FCONTEXT_ALL && type != SEMANAGE_FCONTEXT_DIR) return 0; len = strlen(oexpr); /* Define a macro to strip a literal string from the end of oexpr */ #define rstrip_oexpr_len(cstr, cstrlen) \ do { \ if (len >= (cstrlen) && !strncmp(oexpr + len - (cstrlen), (cstr), (cstrlen))) \ len -= (cstrlen); \ } while (0) #define rstrip_oexpr(cstr) rstrip_oexpr_len(cstr, sizeof(cstr) - 1) rstrip_oexpr(".+"); rstrip_oexpr(".*"); rstrip_oexpr("(/.*)?"); rstrip_oexpr("/"); #undef rstrip_oexpr_len #undef rstrip_oexpr /* Anchor oexpr at the beginning and append pattern to eat up trailing slashes */ if (asprintf(&expr, "^%.*s/*$", (int)len, oexpr) < 0) return -1; /* Check dir against expr */ if (regcomp(&re, expr, REG_EXTENDED) != 0) goto done; if (regexec(&re, handp->dir, 0, NULL, 0) == 0) handp->matched = 1; regfree(&re); retval = 0; done: 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 *path = NULL; uid_t temp, minuid = 500, maxuid = 60000; int minuid_set = 0; struct passwd *pwbuf; struct stat buf; 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(); if (!shells) { ERR(s->h_semanage, "Allocation failure!"); goto fail; } 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; errno = 0; setpwent(); while (1) { errno = 0; pwbuf = getpwent(); if (pwbuf == NULL) break; 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 (errno) { WARN(s->h_semanage, "Error while fetching users. " "Returning list so far."); } if (semanage_list_sort(&homedir_list)) goto fail; endpwent(); semanage_list_destroy(&shells); return homedir_list; fail: endpwent(); 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); } /* new names */ static int USERNAME_CONTEXT_PRED(const char *string) { return strstr(string, TEMPLATE_USERNAME) != NULL || strstr(string, TEMPLATE_USERID) != NULL ; } /* This will never match USER if USERNAME or USERID are found. */ static int USER_CONTEXT_PRED(const char *string) { if (USERNAME_CONTEXT_PRED(string)) return 0; return strstr(string, TEMPLATE_USER) != NULL; } static int STR_COMPARATOR(const void *a, const void *b) { return strcmp((const char *) a, (const char *) b); } /* make_template * @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, "re"); if (!template_file) return NULL; template_data = semanage_slurp_file_filter(template_file, pred); fclose(template_file); return template_data; } static char *replace_all(const char *str, const replacement_pair_t * repl) { char *retval, *retval2; int i; if (!str || !repl) return NULL; retval = strdup(str); for (i = 0; retval != NULL && repl[i].search_for; i++) { retval2 = semanage_str_replace(repl[i].search_for, repl[i].replace_with, retval, 0); free(retval); retval = retval2; } return retval; } static const char *extract_context(const char *line) { const char *p = line; size_t off; off = strlen(p); p += off; /* consider trailing whitespaces */ while (off > 0) { p--; off--; if (!isspace((unsigned char)*p)) break; } if (off == 0) return NULL; /* find the last field in line */ while (off > 0 && !isspace((unsigned char)*(p - 1))) { p--; off--; } return p; } static int check_line(genhomedircon_settings_t * s, const char *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) { result = sepol_context_check(s->h_semanage->sepolh, s->policydb, ctx_record); sepol_context_free(ctx_record); } return result; } static int write_replacements(genhomedircon_settings_t * s, FILE * out, const semanage_list_t * tpl, const replacement_pair_t *repl) { char *line; for (; tpl; tpl = tpl->next) { line = replace_all(tpl->data, repl); if (!line) goto fail; if (check_line(s, line) == STATUS_SUCCESS) { if (fprintf(out, "%s\n", line) < 0) goto fail; } free(line); } return STATUS_SUCCESS; fail: free(line); return STATUS_ERR; } static int write_contexts(genhomedircon_settings_t *s, FILE *out, semanage_list_t *tpl, const replacement_pair_t *repl, const genhomedircon_user_entry_t *user) { char *line, *temp; sepol_context_t *context; char *new_context_str; for (; tpl; tpl = tpl->next) { context = NULL; new_context_str = NULL; line = replace_all(tpl->data, repl); if (!line) { goto fail; } const char *old_context_str = extract_context(line); if (!old_context_str) { goto fail; } if (strcmp(old_context_str, CONTEXT_NONE) == 0) { if (check_line(s, line) == STATUS_SUCCESS && fprintf(out, "%s\n", line) < 0) { goto fail; } free(line); continue; } sepol_handle_t *sepolh = s->h_semanage->sepolh; if (sepol_context_from_string(sepolh, old_context_str, &context) < 0) { goto fail; } if (sepol_context_set_user(sepolh, context, user->sename) < 0) { goto fail; } if (sepol_policydb_mls_enabled(s->policydb) && sepol_context_set_mls(sepolh, context, user->level) < 0) { goto fail; } if (user->homedir_role && sepol_context_set_role(sepolh, context, user->homedir_role) < 0) { goto fail; } if (sepol_context_to_string(sepolh, context, &new_context_str) < 0) { goto fail; } temp = semanage_str_replace(old_context_str, new_context_str, line, 1); if (!temp) { goto fail; } free(line); line = temp; if (check_line(s, line) == STATUS_SUCCESS) { if (fprintf(out, "%s\n", line) < 0) goto fail; } free(line); sepol_context_free(context); free(new_context_str); } return STATUS_SUCCESS; fail: free(line); sepol_context_free(context); free(new_context_str); return STATUS_ERR; } static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out, semanage_list_t * tpl, const genhomedircon_user_entry_t *user) { const replacement_pair_t repl[] = { {.search_for = TEMPLATE_HOME_DIR,.replace_with = user->home}, {.search_for = TEMPLATE_ROLE,.replace_with = user->prefix}, {NULL, NULL} }; if (strcmp(user->name, FALLBACK_NAME) == 0) { if (fprintf(out, COMMENT_USER_HOME_CONTEXT, FALLBACK_SENAME) < 0) return STATUS_ERR; } else { if (fprintf(out, COMMENT_USER_HOME_CONTEXT, user->name) < 0) return STATUS_ERR; } return write_contexts(s, out, tpl, repl, user); } static int write_home_root_context(genhomedircon_settings_t * s, FILE * out, semanage_list_t * tpl, const char *homedir) { const replacement_pair_t repl[] = { {.search_for = TEMPLATE_HOME_ROOT,.replace_with = homedir}, {NULL, NULL} }; return write_replacements(s, out, tpl, repl); } static int write_username_context(genhomedircon_settings_t * s, FILE * out, semanage_list_t * tpl, const genhomedircon_user_entry_t *user) { const replacement_pair_t repl[] = { {.search_for = TEMPLATE_USERNAME,.replace_with = user->name}, {.search_for = TEMPLATE_USERID,.replace_with = user->uid}, {.search_for = TEMPLATE_ROLE,.replace_with = user->prefix}, {NULL, NULL} }; return write_contexts(s, out, tpl, repl, user); } static int write_user_context(genhomedircon_settings_t * s, FILE * out, semanage_list_t * tpl, const genhomedircon_user_entry_t *user) { const replacement_pair_t repl[] = { {.search_for = TEMPLATE_USER,.replace_with = user->name}, {.search_for = TEMPLATE_ROLE,.replace_with = user->prefix}, {NULL, NULL} }; return write_contexts(s, out, tpl, repl, user); } static int seuser_sort_func(const void *arg1, const void *arg2) { const semanage_seuser_t *const *u1 = (const semanage_seuser_t *const *) arg1; const semanage_seuser_t *const *u2 = (const semanage_seuser_t *const *) arg2; const char *name1 = semanage_seuser_get_name(*u1); const char *name2 = semanage_seuser_get_name(*u2); if (name1[0] == '%' && name2[0] == '%') { return 0; } else if (name1[0] == '%') { return 1; } else if (name2[0] == '%') { return -1; } return strcmp(name1, name2); } static int user_sort_func(const void *arg1, const void *arg2) { const semanage_user_t *const *user1 = arg1; const semanage_user_t *const *user2 = arg2; return strcmp(semanage_user_get_name(*user1), semanage_user_get_name(*user2)); } static int name_user_cmp(const void *arg1, const void *arg2) { const char *key = arg1; const semanage_user_t *const *val = arg2; return strcmp(key, semanage_user_get_name(*val)); } static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, const char *u, const char *g, const char *sen, const char *pre, const char *h, const char *l, const char *ln, const char *hd_role) { genhomedircon_user_entry_t *temp = NULL; char *name = NULL; char *uid = NULL; char *gid = NULL; char *sename = NULL; char *prefix = NULL; char *home = NULL; char *level = NULL; char *lname = NULL; char *homedir_role = NULL; temp = malloc(sizeof(genhomedircon_user_entry_t)); if (!temp) goto cleanup; name = strdup(n); if (!name) goto cleanup; uid = strdup(u); if (!uid) goto cleanup; gid = strdup(g); if (!gid) 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; lname = strdup(ln); if (!lname) goto cleanup; if (hd_role) { homedir_role = strdup(hd_role); if (!homedir_role) goto cleanup; } temp->name = name; temp->uid = uid; temp->gid = gid; temp->sename = sename; temp->prefix = prefix; temp->home = home; temp->level = level; temp->login = lname; temp->homedir_role = homedir_role; temp->next = (*list); (*list) = temp; return STATUS_SUCCESS; cleanup: free(name); free(uid); free(gid); free(sename); free(prefix); free(home); free(level); free(lname); free(homedir_role); 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->uid); free(temp->gid); free(temp->sename); free(temp->prefix); free(temp->home); free(temp->level); free(temp->login); free(temp->homedir_role); free(temp); } 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; const char *homedir_role = 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_LEVEL; } else { prefix = semanage_user_get_prefix(u); level = semanage_user_get_mlslevel(u); if (!level) level = FALLBACK_LEVEL; } if (prefix_is_homedir_role(u, prefix)) { homedir_role = prefix; } if (push_user_entry(&(s->fallback), FALLBACK_NAME, FALLBACK_UIDGID, FALLBACK_UIDGID, seuname, prefix, "", level, FALLBACK_NAME, homedir_role) != 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 *find_user(genhomedircon_user_entry_t *head, const char *name) { for(; head; head = head->next) { if (strcmp(head->name, name) == 0) { return head; } } return NULL; } static int add_user(genhomedircon_settings_t * s, genhomedircon_user_entry_t **head, semanage_user_t *user, const char *name, const char *sename, const char *selogin) { if (selogin[0] == '%') { genhomedircon_user_entry_t *orig = find_user(*head, name); if (orig != NULL && orig->login[0] == '%') { ERR(s->h_semanage, "User %s is already mapped to" " group %s, but also belongs to group %s. Add an" " explicit mapping for this user to" " override group mappings.", name, orig->login + 1, selogin + 1); return STATUS_ERR; } else if (orig != NULL) { // user mappings take precedence return STATUS_SUCCESS; } } int retval = STATUS_ERR; char *rbuf = NULL; long rbuflen; struct passwd pwstorage, *pwent = NULL; const char *prefix = NULL; const char *level = NULL; const char *homedir_role = NULL; char uid[11]; char gid[11]; errno = 0; /* Allocate space for the getpwnam_r buffer */ rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); if (rbuflen == -1 && errno == 0) /* sysconf returning -1 with no errno means indeterminate size */ rbuflen = 1024; else if (rbuflen <= 0) goto cleanup; if (user) { prefix = semanage_user_get_prefix(user); level = semanage_user_get_mlslevel(user); if (!level) { level = FALLBACK_LEVEL; } } else { prefix = name; level = FALLBACK_LEVEL; } if (prefix_is_homedir_role(user, prefix)) { homedir_role = prefix; } retry: rbuf = malloc(rbuflen); if (rbuf == NULL) goto cleanup; retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent); if (retval == ERANGE && rbuflen < LONG_MAX / 2) { free(rbuf); rbuflen *= 2; goto retry; } if (retval != 0 || pwent == NULL) { if (retval != 0 && retval != ENOENT) { goto cleanup; } WARN(s->h_semanage, "user %s not in password file", name); retval = STATUS_SUCCESS; goto cleanup; } 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 */ retval = STATUS_SUCCESS; goto cleanup; } if (ignore(pwent->pw_dir)) { retval = STATUS_SUCCESS; goto cleanup; } len = snprintf(uid, sizeof(uid), "%u", pwent->pw_uid); if (len < 0 || len >= (int)sizeof(uid)) { goto cleanup; } len = snprintf(gid, sizeof(gid), "%u", pwent->pw_gid); if (len < 0 || len >= (int)sizeof(gid)) { goto cleanup; } retval = push_user_entry(head, name, uid, gid, sename, prefix, pwent->pw_dir, level, selogin, homedir_role); cleanup: free(rbuf); return retval; } static int get_group_users(genhomedircon_settings_t * s, genhomedircon_user_entry_t **head, semanage_user_t *user, const char *sename, const char *selogin) { int retval = STATUS_ERR; unsigned int i; long grbuflen; char *grbuf = NULL; struct group grstorage, *group = NULL; struct passwd *pw = NULL; errno = 0; grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); if (grbuflen == -1 && errno == 0) /* sysconf returning -1 with no errno means indeterminate size */ grbuflen = 1024; else if (grbuflen <= 0) goto cleanup; grbuf = malloc(grbuflen); if (grbuf == NULL) goto cleanup; const char *grname = selogin + 1; errno = 0; while ( (retval = getgrnam_r(grname, &grstorage, grbuf, (size_t) grbuflen, &group)) != 0 && errno == ERANGE ) { char *new_grbuf; grbuflen *= 2; if (grbuflen < 0) /* the member list could exceed 2Gb on a system with a 32-bit CPU (where * sizeof(long) = 4) - if this ever happened, the loop would become infinite. */ goto cleanup; new_grbuf = realloc(grbuf, grbuflen); if (new_grbuf == NULL) goto cleanup; grbuf = new_grbuf; } if (retval != 0) goto cleanup; if (group == NULL) { ERR(s->h_semanage, "Can't find group named %s.", grname); goto cleanup; } size_t nmembers = 0; char **members = group->gr_mem; while (*members != NULL) { nmembers++; members++; } for (i = 0; i < nmembers; i++) { const char *uname = group->gr_mem[i]; if (add_user(s, head, user, uname, sename, selogin) < 0) { goto cleanup; } } setpwent(); while (1) { errno = 0; pw = getpwent(); if (pw == NULL) break; // skip users who also have this group as their // primary group if (lfind(pw->pw_name, group->gr_mem, &nmembers, sizeof(char *), &STR_COMPARATOR)) { continue; } if (group->gr_gid == pw->pw_gid) { if (add_user(s, head, user, pw->pw_name, sename, selogin) < 0) { goto cleanup; } } } retval = STATUS_SUCCESS; cleanup: endpwent(); free(grbuf); return retval; } 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; unsigned int i; 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(seuser_list, nseusers, sizeof(semanage_seuser_t *), &seuser_sort_func); qsort(user_list, nusers, sizeof(semanage_user_t *), user_sort_func); 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, DEFAULT_LOGIN) == 0) continue; /* find the user structure given the name */ u = bsearch(seuname, user_list, nusers, sizeof(semanage_user_t *), name_user_cmp); /* %groupname syntax */ if (name[0] == '%') { retval = get_group_users(s, &head, *u, seuname, name); } else { retval = add_user(s, &head, *u, name, seuname, name); } if (retval != 0) { *errors = STATUS_ERR; goto cleanup; } } cleanup: 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 * username_context_tpl, 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)) goto err; if (write_username_context(s, out, username_context_tpl, users)) goto err; if (write_user_context(s, out, user_context_tpl, users)) 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 *homedir_context_tpl = NULL; semanage_list_t *homeroot_context_tpl = NULL; semanage_list_t *username_context_tpl = NULL; semanage_list_t *user_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); username_context_tpl = make_template(s, &USERNAME_CONTEXT_PRED); user_context_tpl = make_template(s, &USER_CONTEXT_PRED); if (!homedir_context_tpl && !homeroot_context_tpl && !username_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) { char *temp = NULL; if (asprintf(&temp, "%s/%s", h->data, FALLBACK_NAME) < 0) { retval = STATUS_ERR; goto done; } free(s->fallback->home); s->fallback->home = temp; if (write_home_dir_context(s, out, homedir_context_tpl, s->fallback) != STATUS_SUCCESS) { free(temp); s->fallback->home = NULL; retval = STATUS_ERR; goto done; } if (write_home_root_context(s, out, homeroot_context_tpl, h->data) != STATUS_SUCCESS) { free(temp); s->fallback->home = NULL; retval = STATUS_ERR; goto done; } free(temp); s->fallback->home = NULL; } } if (user_context_tpl || username_context_tpl) { if (write_username_context(s, out, username_context_tpl, s->fallback) != STATUS_SUCCESS) { retval = STATUS_ERR; goto done; } if (write_user_context(s, out, user_context_tpl, s->fallback) != STATUS_SUCCESS) { retval = STATUS_ERR; goto done; } if (write_gen_home_dir_context(s, out, username_context_tpl, user_context_tpl, homedir_context_tpl) != STATUS_SUCCESS) { retval = STATUS_ERR; } } done: /* Cleanup */ semanage_list_destroy(&homedirs); semanage_list_destroy(&username_context_tpl); 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_STORE_FC_HOMEDIRS); s.fallback = calloc(1, sizeof(genhomedircon_user_entry_t)); if (s.fallback == NULL) { retval = STATUS_ERR; goto done; } s.fallback->name = strdup(FALLBACK_NAME); s.fallback->sename = strdup(FALLBACK_SENAME); s.fallback->prefix = strdup(FALLBACK_PREFIX); s.fallback->level = strdup(FALLBACK_LEVEL); if (s.fallback->name == NULL || s.fallback->sename == NULL || s.fallback->prefix == NULL || s.fallback->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, "we"))) { /* 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) if (fclose(out) != 0 && errno != EINTR) retval = STATUS_ERR; while (s.fallback) pop_user_entry(&(s.fallback)); ignore_free(); return retval; } libsemanage-3.8.1/src/genhomedircon.h000066400000000000000000000020711476211737200175650ustar00rootroot00000000000000/* 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-3.8.1/src/handle.c000066400000000000000000000220561476211737200161770ustar00rootroot00000000000000/* 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 #include "direct_api.h" #include "handle.h" #include "debug.h" #include "semanage_conf.h" #include "semanage_store.h" #define SEMANAGE_COMMIT_READ_WAIT 5 static char *private_semanage_root = NULL; int semanage_set_root(const char *root) { free(private_semanage_root); private_semanage_root = strdup(root); if (!private_semanage_root) return -1; return 0; } const char * semanage_root(void) { if (private_semanage_root == NULL) { return ""; } return private_semanage_root; } semanage_handle_t *semanage_handle_create(void) { semanage_handle_t *sh = NULL; 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); /* Default priority is 400 */ sh->priority = 400; /* By default do not rebuild the policy on commit * If any changes are made, this flag is ignored */ sh->do_rebuild = 0; sh->commit_err = 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; free(conf_name); return sh; err: free(conf_name); 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; } void semanage_set_reload(semanage_handle_t * sh, int do_reload) { assert(sh != NULL); sh->do_reload = do_reload; } void semanage_set_check_ext_changes(semanage_handle_t * sh, int do_check) { assert(sh != NULL); sh->check_ext_changes = do_check; } int semanage_get_hll_compiler_path(semanage_handle_t *sh, const char *lang_ext, char **compiler_path) { size_t i; int status = 0; char *compiler = NULL; char *lower_lang_ext = NULL; assert(sh != NULL); assert(lang_ext != NULL); lower_lang_ext = strdup(lang_ext); if (lower_lang_ext == NULL) { ERR(sh, "Could not create copy of lang_ext. Out of memory."); status = -1; goto cleanup; } /* Set lang_ext to lowercase in case a file with a mixed case extension was passed to libsemanage */ for (i = 0; lower_lang_ext[i] != '\0'; i++) { lower_lang_ext[i] = tolower(lower_lang_ext[i]); } if (asprintf(&compiler, "%s/%s", sh->conf->compiler_directory_path, lower_lang_ext) < 0) { ERR(sh, "Error creating compiler path."); status = -1; goto cleanup; } *compiler_path = compiler; status = 0; cleanup: free(lower_lang_ext); return status; } void semanage_set_create_store(semanage_handle_t * sh, int create_store) { assert(sh != NULL); sh->create_store = create_store; } 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); } 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); } int semanage_get_ignore_module_cache(semanage_handle_t *sh) { assert(sh != NULL); return sh->conf->ignore_module_cache; } void semanage_set_ignore_module_cache(semanage_handle_t *sh, int ignore_module_cache) { assert(sh != NULL); sh->conf->ignore_module_cache = ignore_module_cache; } void semanage_set_check_contexts(semanage_handle_t * sh, int do_check_contexts) { assert(sh != NULL); sh->do_check_contexts = do_check_contexts; } uint16_t semanage_get_default_priority(semanage_handle_t *sh) { assert(sh != NULL); return sh->priority; } int semanage_set_default_priority(semanage_handle_t *sh, uint16_t priority) { assert(sh != NULL); /* Verify priority */ if (semanage_module_validate_priority(priority) < 0) { ERR(sh, "Priority %d is invalid.", priority); return -1; } sh->priority = priority; return 0; } int semanage_is_connected(semanage_handle_t * sh) { assert(sh != NULL); return sh->is_connected; } void semanage_select_store(semanage_handle_t * sh, const char *storename, enum semanage_connect_type storetype) { assert(sh != NULL); /* This just sets the storename to what the user requests, no verification of existence will be done until connect */ free(sh->conf->store_path); sh->conf->store_path = strdup(storename); assert(sh->conf->store_path); /* no way to return failure */ sh->conf->store_type = storetype; } void semanage_set_store_root(semanage_handle_t *sh, const char *store_root) { assert(sh != NULL); free(sh->conf->store_root_path); sh->conf->store_root_path = strdup(store_root); assert(sh->conf->store_root_path); /* no way to return failure */ } 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; } } int semanage_disconnect(semanage_handle_t * sh) { assert(sh != NULL); if (!sh->is_connected) { return 0; } if (sh->funcs && 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); } /********************* 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; } 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-3.8.1/src/handle.h000066400000000000000000000164101476211737200162010ustar00rootroot00000000000000/* 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 #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; uint16_t priority; 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 check_ext_changes; /* whether to rebuild if external changes are detected via checksum */ int commit_err; /* set by semanage_direct_commit() if there are * any errors when building or committing the * sandbox to kernel policy at /etc/selinux */ 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 indefinitely 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. */ const struct semanage_policy_table *funcs; /* Object databases */ #define DBASE_COUNT 24 /* 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 #define DBASE_LOCAL_IBPKEYS 9 #define DBASE_LOCAL_IBENDPORTS 10 /* Policy + Local modifications */ #define DBASE_POLICY_USERS_BASE 11 #define DBASE_POLICY_USERS_EXTRA 12 #define DBASE_POLICY_USERS 13 #define DBASE_POLICY_PORTS 14 #define DBASE_POLICY_INTERFACES 15 #define DBASE_POLICY_BOOLEANS 16 #define DBASE_POLICY_FCONTEXTS 17 #define DBASE_POLICY_FCONTEXTS_H 18 #define DBASE_POLICY_SEUSERS 19 #define DBASE_POLICY_NODES 20 #define DBASE_POLICY_IBPKEYS 21 #define DBASE_POLICY_IBENDPORTS 22 /* Active kernel policy */ #define DBASE_ACTIVE_BOOLEANS 23 dbase_config_t dbase[DBASE_COUNT]; }; /* === 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_ibpkey_dbase_local(semanage_handle_t * handle) { return &handle->dbase[DBASE_LOCAL_IBPKEYS]; } static inline dbase_config_t * semanage_ibendport_dbase_local(semanage_handle_t * handle) { return &handle->dbase[DBASE_LOCAL_IBENDPORTS]; } 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_ibpkey_dbase_policy(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_IBPKEYS]; } static inline dbase_config_t * semanage_ibendport_dbase_policy(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_IBENDPORTS]; } 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_fcontext_dbase_homedirs(semanage_handle_t * handle) { return &handle->dbase[DBASE_POLICY_FCONTEXTS_H]; } 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-3.8.1/src/ibendport_internal.h000066400000000000000000000016471476211737200206360ustar00rootroot00000000000000#ifndef _SEMANAGE_IBENDPORT_INTERNAL_H_ #define _SEMANAGE_IBENDPORT_INTERNAL_H_ #include #include #include #include "database.h" #include "handle.h" /* IBENDPORT RECORD: method table */ extern const record_table_t SEMANAGE_IBENDPORT_RTABLE; extern int ibendport_file_dbase_init(semanage_handle_t *handle, const char *path_ro, const char *path_rw, dbase_config_t *dconfig); extern void ibendport_file_dbase_release(dbase_config_t *dconfig); extern int ibendport_policydb_dbase_init(semanage_handle_t *handle, dbase_config_t *dconfig); extern void ibendport_policydb_dbase_release(dbase_config_t *dconfig); extern int semanage_ibendport_validate_local(semanage_handle_t *handle); /* ==== Internal (to ibendports) API === */ int semanage_ibendport_compare2_qsort(const void *p1, const void *p2); #endif libsemanage-3.8.1/src/ibendport_record.c000066400000000000000000000074121476211737200202670ustar00rootroot00000000000000/*Copyright (C) 2005 Red Hat, Inc. */ /*Object: semanage_ibendport_t (Infiniband Pkey) *Object: semanage_ibendport_key_t (Infiniband Pkey Key) *Implements: record_t (Database Record) *Implements: record_key_t (Database Record Key) */ #include #include typedef sepol_context_t semanage_context_t; typedef sepol_ibendport_t semanage_ibendport_t; typedef sepol_ibendport_key_t semanage_ibendport_key_t; #define _SEMANAGE_IBENDPORT_DEFINED_ #define _SEMANAGE_CONTEXT_DEFINED_ typedef semanage_ibendport_t record_t; typedef semanage_ibendport_key_t record_key_t; #define DBASE_RECORD_DEFINED #include "ibendport_internal.h" #include "handle.h" #include "database.h" int semanage_ibendport_compare(const semanage_ibendport_t *ibendport, const semanage_ibendport_key_t *key) { return sepol_ibendport_compare(ibendport, key); } int semanage_ibendport_compare2(const semanage_ibendport_t *ibendport, const semanage_ibendport_t *ibendport2) { return sepol_ibendport_compare2(ibendport, ibendport2); } int semanage_ibendport_compare2_qsort(const void *p1, const void *p2) { const semanage_ibendport_t *const *ibendport1 = p1; const semanage_ibendport_t *const *ibendport2 = p2; return sepol_ibendport_compare2(*ibendport1, *ibendport2); } int semanage_ibendport_key_create(semanage_handle_t *handle, const char *ibdev_name, int port, semanage_ibendport_key_t **key_ptr) { return sepol_ibendport_key_create(handle->sepolh, ibdev_name, port, key_ptr); } int semanage_ibendport_key_extract(semanage_handle_t *handle, const semanage_ibendport_t *ibendport, semanage_ibendport_key_t **key_ptr) { return sepol_ibendport_key_extract(handle->sepolh, ibendport, key_ptr); } void semanage_ibendport_key_free(semanage_ibendport_key_t *key) { sepol_ibendport_key_free(key); } int semanage_ibendport_get_ibdev_name(semanage_handle_t *handle, const semanage_ibendport_t *ibendport, char **ibdev_name_ptr) { return sepol_ibendport_get_ibdev_name(handle->sepolh, ibendport, ibdev_name_ptr); } int semanage_ibendport_set_ibdev_name(semanage_handle_t *handle, semanage_ibendport_t *ibendport, const char *ibdev_name) { return sepol_ibendport_set_ibdev_name(handle->sepolh, ibendport, ibdev_name); } int semanage_ibendport_get_port(const semanage_ibendport_t *ibendport) { return sepol_ibendport_get_port(ibendport); } void semanage_ibendport_set_port(semanage_ibendport_t *ibendport, int port) { sepol_ibendport_set_port(ibendport, port); } semanage_context_t *semanage_ibendport_get_con(const semanage_ibendport_t *ibendport) { return sepol_ibendport_get_con(ibendport); } int semanage_ibendport_set_con(semanage_handle_t *handle, semanage_ibendport_t *ibendport, semanage_context_t *con) { return sepol_ibendport_set_con(handle->sepolh, ibendport, con); } int semanage_ibendport_create(semanage_handle_t *handle, semanage_ibendport_t **ibendport_ptr) { return sepol_ibendport_create(handle->sepolh, ibendport_ptr); } int semanage_ibendport_clone(semanage_handle_t *handle, const semanage_ibendport_t *ibendport, semanage_ibendport_t **ibendport_ptr) { return sepol_ibendport_clone(handle->sepolh, ibendport, ibendport_ptr); } void semanage_ibendport_free(semanage_ibendport_t *ibendport) { sepol_ibendport_free(ibendport); } /*key base functions */ const record_table_t SEMANAGE_IBENDPORT_RTABLE = { .create = semanage_ibendport_create, .key_extract = semanage_ibendport_key_extract, .key_free = semanage_ibendport_key_free, .clone = semanage_ibendport_clone, .compare = semanage_ibendport_compare, .compare2 = semanage_ibendport_compare2, .compare2_qsort = semanage_ibendport_compare2_qsort, .free = semanage_ibendport_free, }; libsemanage-3.8.1/src/ibendports_file.c000066400000000000000000000072331476211737200201140ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Technologies Inc. */ struct semanage_ibendport; struct semanage_ibendport_key; typedef struct semanage_ibendport record_t; typedef struct semanage_ibendport_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 "ibendport_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" static int ibendport_print(semanage_handle_t *handle, const semanage_ibendport_t *ibendport, FILE *str) { const semanage_context_t *con; char *con_str = NULL; char *ibdev_name_str = NULL; int port = semanage_ibendport_get_port(ibendport); if (semanage_ibendport_get_ibdev_name(handle, ibendport, &ibdev_name_str) != 0) goto err; con = semanage_ibendport_get_con(ibendport); if (fprintf(str, "ibendportcon %s ", ibdev_name_str) < 0) goto err; if (fprintf(str, "%d ", port) < 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(ibdev_name_str); free(con_str); return STATUS_SUCCESS; err: ERR(handle, "could not print ibendport (%s) %u to stream", ibdev_name_str, port); free(ibdev_name_str); free(con_str); return STATUS_ERR; } static int ibendport_parse(semanage_handle_t *handle, parse_info_t *info, semanage_ibendport_t *ibendport) { int port; 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, "ibendportcon") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* IB Device Name */ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0) goto err; if (semanage_ibendport_set_ibdev_name(handle, ibendport, str) < 0) goto err; free(str); str = NULL; /* Port */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_fetch_int(handle, info, &port, ' ') < 0) goto err; semanage_ibendport_set_port(ibendport, port); /* context */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_fetch_string(handle, info, &str, ' ', 0) < 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) { ERR(handle, "<> context is not valid for ibendport (%s: %u):\n%s", info->filename, info->lineno, info->orig_line); goto err; } free(str); str = NULL; if (semanage_ibendport_set_con(handle, ibendport, 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 ibendport record"); free(str); semanage_context_free(con); parse_dispose_line(info); return STATUS_ERR; } /* IBENDPORT RECORD: FILE extension: method table */ static const record_file_table_t SEMANAGE_IBENDPORT_FILE_RTABLE = { .parse = ibendport_parse, .print = ibendport_print, }; int ibendport_file_dbase_init(semanage_handle_t *handle, const char *path_ro, const char *path_rw, dbase_config_t *dconfig) { if (dbase_file_init(handle, path_ro, path_rw, &SEMANAGE_IBENDPORT_RTABLE, &SEMANAGE_IBENDPORT_FILE_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_FILE_DTABLE; return STATUS_SUCCESS; } void ibendport_file_dbase_release(dbase_config_t *dconfig) { dbase_file_release(dconfig->dbase); } libsemanage-3.8.1/src/ibendports_local.c000066400000000000000000000077511476211737200202740ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Technologies Inc */ struct semanage_ibendport; struct semanage_ibendport_key; typedef struct semanage_ibendport_key record_key_t; typedef struct semanage_ibendport record_t; #define DBASE_RECORD_DEFINED #include #include #include #include "ibendport_internal.h" #include "debug.h" #include "handle.h" #include "database.h" int semanage_ibendport_modify_local(semanage_handle_t *handle, const semanage_ibendport_key_t *key, const semanage_ibendport_t *data) { dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); return dbase_modify(handle, dconfig, key, data); } int semanage_ibendport_del_local(semanage_handle_t *handle, const semanage_ibendport_key_t *key) { dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); return dbase_del(handle, dconfig, key); } int semanage_ibendport_query_local(semanage_handle_t *handle, const semanage_ibendport_key_t *key, semanage_ibendport_t **response) { dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); return dbase_query(handle, dconfig, key, response); } int semanage_ibendport_exists_local(semanage_handle_t *handle, const semanage_ibendport_key_t *key, int *response) { dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_ibendport_count_local(semanage_handle_t *handle, unsigned int *response) { dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); return dbase_count(handle, dconfig, response); } int semanage_ibendport_iterate_local(semanage_handle_t *handle, int (*handler)(const semanage_ibendport_t *record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_ibendport_list_local(semanage_handle_t *handle, semanage_ibendport_t ***records, unsigned int *count) { dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); return dbase_list(handle, dconfig, records, count); } int semanage_ibendport_validate_local(semanage_handle_t *handle) { semanage_ibendport_t **ibendports = NULL; unsigned int nibendports = 0; unsigned int i = 0, j = 0; char *ibdev_name = NULL; char *ibdev_name2 = NULL; int port; int port2; /* List and sort the ibendports */ if (semanage_ibendport_list_local(handle, &ibendports, &nibendports) < 0) goto err; if (nibendports > 1) qsort(ibendports, nibendports, sizeof(semanage_ibendport_t *), semanage_ibendport_compare2_qsort); /* Test each ibendport */ while (i < nibendports) { int stop = 0; free(ibdev_name); ibdev_name = NULL; if (STATUS_SUCCESS != semanage_ibendport_get_ibdev_name(handle, ibendports[i], &ibdev_name)) { ERR(handle, "Couldn't get IB device name"); goto err; } port = semanage_ibendport_get_port(ibendports[i]); /* Find the first ibendport with matching * ibdev_name to compare against */ do { if (j == nibendports - 1) goto next; j++; free(ibdev_name2); ibdev_name2 = NULL; if (STATUS_SUCCESS != semanage_ibendport_get_ibdev_name(handle, ibendports[j], &ibdev_name2)) { ERR(handle, "Couldn't get IB device name."); goto err; } port2 = semanage_ibendport_get_port(ibendports[j]); stop = !strcmp(ibdev_name, ibdev_name2); } while (!stop); if (port == port2) { ERR(handle, "ibendport %s/%u already exists.", ibdev_name2, port2); goto invalid; } next: i++; j = i; } free(ibdev_name); free(ibdev_name2); for (i = 0; i < nibendports; i++) semanage_ibendport_free(ibendports[i]); free(ibendports); return STATUS_SUCCESS; err: ERR(handle, "could not complete ibendports validity check"); invalid: free(ibdev_name); free(ibdev_name2); for (i = 0; i < nibendports; i++) semanage_ibendport_free(ibendports[i]); free(ibendports); return STATUS_ERR; } libsemanage-3.8.1/src/ibendports_policy.c000066400000000000000000000030701476211737200204670ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Technologies Inc */ struct semanage_ibendport; struct semanage_ibendport_key; typedef struct semanage_ibendport_key record_key_t; typedef struct semanage_ibendport record_t; #define DBASE_RECORD_DEFINED #include "ibendport_internal.h" #include "handle.h" #include "database.h" int semanage_ibendport_query(semanage_handle_t *handle, const semanage_ibendport_key_t *key, semanage_ibendport_t **response) { dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle); return dbase_query(handle, dconfig, key, response); } int semanage_ibendport_exists(semanage_handle_t *handle, const semanage_ibendport_key_t *key, int *response) { dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_ibendport_count(semanage_handle_t *handle, unsigned int *response) { dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle); return dbase_count(handle, dconfig, response); } int semanage_ibendport_iterate(semanage_handle_t *handle, int (*handler)(const semanage_ibendport_t *record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_ibendport_list(semanage_handle_t *handle, semanage_ibendport_t ***records, unsigned int *count) { dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-3.8.1/src/ibendports_policydb.c000066400000000000000000000040321476211737200207740ustar00rootroot00000000000000/* * Copyright (C) 2017 Mellanox Technologies 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. */ struct semanage_ibendport; struct semanage_ibendport_key; typedef struct semanage_ibendport record_t; typedef struct semanage_ibendport_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_policydb; typedef struct dbase_policydb dbase_t; #define DBASE_DEFINED #include #include #include "ibendport_internal.h" #include "debug.h" #include "database_policydb.h" #include "semanage_store.h" /* IBENDPORT RECORD (SEPOL): POLICYDB extension : method table */ static const record_policydb_table_t SEMANAGE_IBENDPORT_POLICYDB_RTABLE = { .add = NULL, .modify = (record_policydb_table_modify_t)sepol_ibendport_modify, .set = NULL, .query = (record_policydb_table_query_t)sepol_ibendport_query, .count = (record_policydb_table_count_t)sepol_ibendport_count, .exists = (record_policydb_table_exists_t)sepol_ibendport_exists, .iterate = (record_policydb_table_iterate_t)sepol_ibendport_iterate, }; int ibendport_policydb_dbase_init(semanage_handle_t *handle, dbase_config_t *dconfig) { if (dbase_policydb_init(handle, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL), semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), &SEMANAGE_IBENDPORT_RTABLE, &SEMANAGE_IBENDPORT_POLICYDB_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE; return STATUS_SUCCESS; } void ibendport_policydb_dbase_release(dbase_config_t *dconfig) { dbase_policydb_release(dconfig->dbase); } libsemanage-3.8.1/src/ibpkey_internal.h000066400000000000000000000015661476211737200201330ustar00rootroot00000000000000#ifndef _SEMANAGE_IBPKEY_INTERNAL_H_ #define _SEMANAGE_IBPKEY_INTERNAL_H_ #include #include #include #include "database.h" #include "handle.h" /* PKEY RECORD: method table */ extern const record_table_t SEMANAGE_IBPKEY_RTABLE; extern int ibpkey_file_dbase_init(semanage_handle_t *handle, const char *path_ro, const char *path_rw, dbase_config_t *dconfig); extern void ibpkey_file_dbase_release(dbase_config_t *dconfig); extern int ibpkey_policydb_dbase_init(semanage_handle_t *handle, dbase_config_t *dconfig); extern void ibpkey_policydb_dbase_release(dbase_config_t *dconfig); extern int semanage_ibpkey_validate_local(semanage_handle_t *handle); /* ==== Internal (to ibpkeys) API === */ int semanage_ibpkey_compare2_qsort(const void *p1, const void *p2); #endif libsemanage-3.8.1/src/ibpkey_record.c000066400000000000000000000100771476211737200175650ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Technologies Inc. */ /* Object: semanage_ibpkey_t (Infiniband Pkey) * Object: semanage_ibpkey_key_t (Infiniband Pkey Key) * Implements: record_t (Database Record) * Implements: record_key_t (Database Record Key) */ #include #include typedef sepol_context_t semanage_context_t; typedef sepol_ibpkey_t semanage_ibpkey_t; typedef sepol_ibpkey_key_t semanage_ibpkey_key_t; #define _SEMANAGE_IBPKEY_DEFINED_ #define _SEMANAGE_CONTEXT_DEFINED_ typedef semanage_ibpkey_t record_t; typedef semanage_ibpkey_key_t record_key_t; #define DBASE_RECORD_DEFINED #include "ibpkey_internal.h" #include "handle.h" #include "database.h" int semanage_ibpkey_compare(const semanage_ibpkey_t *ibpkey, const semanage_ibpkey_key_t *key) { return sepol_ibpkey_compare(ibpkey, key); } int semanage_ibpkey_compare2(const semanage_ibpkey_t *ibpkey, const semanage_ibpkey_t *ibpkey2) { return sepol_ibpkey_compare2(ibpkey, ibpkey2); } int semanage_ibpkey_compare2_qsort(const void *p1, const void *p2) { const semanage_ibpkey_t *const *ibpkey1 = p1; const semanage_ibpkey_t *const *ibpkey2 = p2; return sepol_ibpkey_compare2(*ibpkey1, *ibpkey2); } int semanage_ibpkey_key_create(semanage_handle_t *handle, const char *subnet_prefix, int low, int high, semanage_ibpkey_key_t **key_ptr) { return sepol_ibpkey_key_create(handle->sepolh, subnet_prefix, low, high, key_ptr); } int semanage_ibpkey_key_extract(semanage_handle_t *handle, const semanage_ibpkey_t *ibpkey, semanage_ibpkey_key_t **key_ptr) { return sepol_ibpkey_key_extract(handle->sepolh, ibpkey, key_ptr); } void semanage_ibpkey_key_free(semanage_ibpkey_key_t *key) { sepol_ibpkey_key_free(key); } int semanage_ibpkey_get_subnet_prefix(semanage_handle_t *handle, const semanage_ibpkey_t *ibpkey, char **subnet_prefix_ptr) { return sepol_ibpkey_get_subnet_prefix(handle->sepolh, ibpkey, subnet_prefix_ptr); } uint64_t semanage_ibpkey_get_subnet_prefix_bytes(const semanage_ibpkey_t *ibpkey) { return sepol_ibpkey_get_subnet_prefix_bytes(ibpkey); } int semanage_ibpkey_set_subnet_prefix(semanage_handle_t *handle, semanage_ibpkey_t *ibpkey, const char *subnet_prefix) { return sepol_ibpkey_set_subnet_prefix(handle->sepolh, ibpkey, subnet_prefix); } void semanage_ibpkey_set_subnet_prefix_bytes(semanage_ibpkey_t *ibpkey, uint64_t subnet_prefix) { return sepol_ibpkey_set_subnet_prefix_bytes(ibpkey, subnet_prefix); } int semanage_ibpkey_get_low(const semanage_ibpkey_t *ibpkey) { return sepol_ibpkey_get_low(ibpkey); } int semanage_ibpkey_get_high(const semanage_ibpkey_t *ibpkey) { return sepol_ibpkey_get_high(ibpkey); } void semanage_ibpkey_set_pkey(semanage_ibpkey_t *ibpkey, int ibpkey_num) { sepol_ibpkey_set_pkey(ibpkey, ibpkey_num); } void semanage_ibpkey_set_range(semanage_ibpkey_t *ibpkey, int low, int high) { sepol_ibpkey_set_range(ibpkey, low, high); } semanage_context_t *semanage_ibpkey_get_con(const semanage_ibpkey_t *ibpkey) { return sepol_ibpkey_get_con(ibpkey); } int semanage_ibpkey_set_con(semanage_handle_t *handle, semanage_ibpkey_t *ibpkey, semanage_context_t *con) { return sepol_ibpkey_set_con(handle->sepolh, ibpkey, con); } int semanage_ibpkey_create(semanage_handle_t *handle, semanage_ibpkey_t **ibpkey_ptr) { return sepol_ibpkey_create(handle->sepolh, ibpkey_ptr); } int semanage_ibpkey_clone(semanage_handle_t *handle, const semanage_ibpkey_t *ibpkey, semanage_ibpkey_t **ibpkey_ptr) { return sepol_ibpkey_clone(handle->sepolh, ibpkey, ibpkey_ptr); } void semanage_ibpkey_free(semanage_ibpkey_t *ibpkey) { sepol_ibpkey_free(ibpkey); } /* key base functions */ const record_table_t SEMANAGE_IBPKEY_RTABLE = { .create = semanage_ibpkey_create, .key_extract = semanage_ibpkey_key_extract, .key_free = semanage_ibpkey_key_free, .clone = semanage_ibpkey_clone, .compare = semanage_ibpkey_compare, .compare2 = semanage_ibpkey_compare2, .compare2_qsort = semanage_ibpkey_compare2_qsort, .free = semanage_ibpkey_free, }; libsemanage-3.8.1/src/ibpkeys_file.c000066400000000000000000000103721476211737200174070ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Technologies Inc. */ struct semanage_ibpkey; struct semanage_ibpkey_key; typedef struct semanage_ibpkey record_t; typedef struct semanage_ibpkey_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 "ibpkey_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" static int ibpkey_print(semanage_handle_t *handle, const semanage_ibpkey_t *ibpkey, FILE *str) { const semanage_context_t *con; char *con_str = NULL; char *subnet_prefix_str = NULL; int low = semanage_ibpkey_get_low(ibpkey); int high = semanage_ibpkey_get_high(ibpkey); if (semanage_ibpkey_get_subnet_prefix(handle, ibpkey, &subnet_prefix_str) != 0) goto err; con = semanage_ibpkey_get_con(ibpkey); if (fprintf(str, "ibpkeycon %s ", subnet_prefix_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(subnet_prefix_str); free(con_str); return STATUS_SUCCESS; err: ERR(handle, "could not print ibpkey range (%s) %u - %u to stream", subnet_prefix_str, low, high); free(subnet_prefix_str); free(con_str); return STATUS_ERR; } static int ibpkey_parse(semanage_handle_t *handle, parse_info_t *info, semanage_ibpkey_t *ibpkey) { 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, "ibpkeycon") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* Subnet Prefix */ if (parse_fetch_string(handle, info, &str, ' ', 0) < 0) goto err; if (semanage_ibpkey_set_subnet_prefix(handle, ibpkey, str) < 0) goto err; free(str); str = NULL; /* Range/Pkey */ 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 ibpkey 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_ibpkey_set_range(ibpkey, low, high); } else { semanage_ibpkey_set_pkey(ibpkey, low); } /* Pkey context */ if (parse_fetch_string(handle, info, &str, ' ', 0) < 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) { ERR(handle, "<> context is not valid for ibpkeys (%s: %u):\n%s", info->filename, info->lineno, info->orig_line); goto err; } free(str); str = NULL; if (semanage_ibpkey_set_con(handle, ibpkey, 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 ibpkey record"); free(str); semanage_context_free(con); parse_dispose_line(info); return STATUS_ERR; } /* IBPKEY RECORD: FILE extension: method table */ static const record_file_table_t SEMANAGE_IBPKEY_FILE_RTABLE = { .parse = ibpkey_parse, .print = ibpkey_print, }; int ibpkey_file_dbase_init(semanage_handle_t *handle, const char *path_ro, const char *path_rw, dbase_config_t *dconfig) { if (dbase_file_init(handle, path_ro, path_rw, &SEMANAGE_IBPKEY_RTABLE, &SEMANAGE_IBPKEY_FILE_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_FILE_DTABLE; return STATUS_SUCCESS; } void ibpkey_file_dbase_release(dbase_config_t *dconfig) { dbase_file_release(dconfig->dbase); } libsemanage-3.8.1/src/ibpkeys_local.c000066400000000000000000000103611476211737200175600ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Technologies Inc. */ struct semanage_ibpkey; struct semanage_ibpkey_key; typedef struct semanage_ibpkey_key record_key_t; typedef struct semanage_ibpkey record_t; #define DBASE_RECORD_DEFINED #include #include #include #include "ibpkey_internal.h" #include "debug.h" #include "handle.h" #include "database.h" int semanage_ibpkey_modify_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, const semanage_ibpkey_t *data) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_modify(handle, dconfig, key, data); } int semanage_ibpkey_del_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_del(handle, dconfig, key); } int semanage_ibpkey_query_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, semanage_ibpkey_t **response) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_query(handle, dconfig, key, response); } int semanage_ibpkey_exists_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, int *response) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_ibpkey_count_local(semanage_handle_t *handle, unsigned int *response) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_count(handle, dconfig, response); } int semanage_ibpkey_iterate_local(semanage_handle_t *handle, int (*handler)(const semanage_ibpkey_t *record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_ibpkey_list_local(semanage_handle_t *handle, semanage_ibpkey_t ***records, unsigned int *count) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_list(handle, dconfig, records, count); } int semanage_ibpkey_validate_local(semanage_handle_t *handle) { semanage_ibpkey_t **ibpkeys = NULL; unsigned int nibpkeys = 0; unsigned int i = 0, j = 0; uint64_t subnet_prefix; uint64_t subnet_prefix2; char *subnet_prefix_str; char *subnet_prefix_str2; int low, high; int low2, high2; /* List and sort the ibpkeys */ if (semanage_ibpkey_list_local(handle, &ibpkeys, &nibpkeys) < 0) goto err; if (nibpkeys > 1) qsort(ibpkeys, nibpkeys, sizeof(semanage_ibpkey_t *), semanage_ibpkey_compare2_qsort); /* Test each ibpkey for overlap */ while (i < nibpkeys) { if (STATUS_SUCCESS != semanage_ibpkey_get_subnet_prefix(handle, ibpkeys[i], &subnet_prefix_str)) { ERR(handle, "Couldn't get subnet prefix string"); goto err; } subnet_prefix = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[i]); low = semanage_ibpkey_get_low(ibpkeys[i]); high = semanage_ibpkey_get_high(ibpkeys[i]); /* Find the first ibpkey with matching * subnet_prefix to compare against */ do { if (j == nibpkeys - 1) goto next; j++; if (STATUS_SUCCESS != semanage_ibpkey_get_subnet_prefix(handle, ibpkeys[j], &subnet_prefix_str2)) { ERR(handle, "Couldn't get subnet prefix string"); goto err; } subnet_prefix2 = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[j]); low2 = semanage_ibpkey_get_low(ibpkeys[j]); high2 = semanage_ibpkey_get_high(ibpkeys[j]); } while (subnet_prefix != subnet_prefix2); /* Overlap detected */ if (low2 <= high) { ERR(handle, "ibpkey overlap between ranges " "(%s) %u - %u <--> (%s) %u - %u.", subnet_prefix_str, low, high, subnet_prefix_str2, low2, high2); goto invalid; } /* If closest ibpkey of matching subnet prefix doesn't overlap * with test ibpkey, neither do the rest of them, because that's * how the sort function works on ibpkeys - lower bound * ibpkeys come first */ next: i++; j = i; } for (i = 0; i < nibpkeys; i++) semanage_ibpkey_free(ibpkeys[i]); free(ibpkeys); return STATUS_SUCCESS; err: ERR(handle, "could not complete ibpkeys validity check"); invalid: for (i = 0; i < nibpkeys; i++) semanage_ibpkey_free(ibpkeys[i]); free(ibpkeys); return STATUS_ERR; } libsemanage-3.8.1/src/ibpkeys_policy.c000066400000000000000000000027231476211737200177700ustar00rootroot00000000000000/* Copyright (C) 2017 Mellanox Technologies Inc. */ struct semanage_ibpkey; struct semanage_ibpkey_key; typedef struct semanage_ibpkey_key record_key_t; typedef struct semanage_ibpkey record_t; #define DBASE_RECORD_DEFINED #include "ibpkey_internal.h" #include "handle.h" #include "database.h" int semanage_ibpkey_query(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, semanage_ibpkey_t **response) { dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle); return dbase_query(handle, dconfig, key, response); } int semanage_ibpkey_exists(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, int *response) { dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_ibpkey_count(semanage_handle_t *handle, unsigned int *response) { dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle); return dbase_count(handle, dconfig, response); } int semanage_ibpkey_iterate(semanage_handle_t *handle, int (*handler)(const semanage_ibpkey_t *record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_ibpkey_list(semanage_handle_t *handle, semanage_ibpkey_t ***records, unsigned int *count) { dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-3.8.1/src/ibpkeys_policydb.c000066400000000000000000000037511476211737200203000ustar00rootroot00000000000000/* * Copyright (C) 2017 Mellanox Technologies 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. */ struct semanage_ibpkey; struct semanage_ibpkey_key; typedef struct semanage_ibpkey record_t; typedef struct semanage_ibpkey_key record_key_t; #define DBASE_RECORD_DEFINED struct dbase_policydb; typedef struct dbase_policydb dbase_t; #define DBASE_DEFINED #include #include #include "ibpkey_internal.h" #include "debug.h" #include "database_policydb.h" #include "semanage_store.h" /* PKEY RECORD (SEPOL): POLICYDB extension : method table */ static const record_policydb_table_t SEMANAGE_IBPKEY_POLICYDB_RTABLE = { .add = NULL, .modify = (record_policydb_table_modify_t)sepol_ibpkey_modify, .set = NULL, .query = (record_policydb_table_query_t)sepol_ibpkey_query, .count = (record_policydb_table_count_t)sepol_ibpkey_count, .exists = (record_policydb_table_exists_t)sepol_ibpkey_exists, .iterate = (record_policydb_table_iterate_t)sepol_ibpkey_iterate, }; int ibpkey_policydb_dbase_init(semanage_handle_t *handle, dbase_config_t *dconfig) { if (dbase_policydb_init(handle, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL), semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), &SEMANAGE_IBPKEY_RTABLE, &SEMANAGE_IBPKEY_POLICYDB_RTABLE, &dconfig->dbase) < 0) return STATUS_ERR; dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE; return STATUS_SUCCESS; } void ibpkey_policydb_dbase_release(dbase_config_t *dconfig) { dbase_policydb_release(dconfig->dbase); } libsemanage-3.8.1/src/iface_internal.h000066400000000000000000000013001476211737200177010ustar00rootroot00000000000000#ifndef _SEMANAGE_IFACE_INTERNAL_H_ #define _SEMANAGE_IFACE_INTERNAL_H_ #include #include #include #include "database.h" #include "handle.h" /* IFACE RECORD: method table */ extern const 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 *path_ro, const char *path_rw, dbase_config_t * dconfig); extern void iface_file_dbase_release(dbase_config_t * dconfig); #endif libsemanage-3.8.1/src/iface_record.c000066400000000000000000000066261476211737200173560ustar00rootroot00000000000000/* 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); } int semanage_iface_compare2(const semanage_iface_t * iface, const semanage_iface_t * iface2) { return sepol_iface_compare2(iface, iface2); } static int semanage_iface_compare2_qsort(const void *p1, const void *p2) { const semanage_iface_t *const *iface1 = p1; const semanage_iface_t *const *iface2 = p2; return sepol_iface_compare2(*iface1, *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); } void semanage_iface_key_free(semanage_iface_key_t * key) { sepol_iface_key_free(key); } /* Name */ const char *semanage_iface_get_name(const semanage_iface_t * iface) { return sepol_iface_get_name(iface); } 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); } /* Context */ semanage_context_t *semanage_iface_get_ifcon(const semanage_iface_t * iface) { return sepol_iface_get_ifcon(iface); } 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); } semanage_context_t *semanage_iface_get_msgcon(const semanage_iface_t * iface) { return sepol_iface_get_msgcon(iface); } 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); } /* Create/Clone/Destroy */ int semanage_iface_create(semanage_handle_t * handle, semanage_iface_t ** iface_ptr) { return sepol_iface_create(handle->sepolh, iface_ptr); } 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); } void semanage_iface_free(semanage_iface_t * iface) { sepol_iface_free(iface); } /* Record base functions */ const 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-3.8.1/src/interfaces_file.c000066400000000000000000000077561476211737200201000ustar00rootroot00000000000000/* 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 "database_file.h" #include "parse_utils.h" #include "debug.h" static int iface_print(semanage_handle_t * handle, const 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) < 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) < 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) < 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 */ static const 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 *path_ro, const char *path_rw, dbase_config_t * dconfig) { if (dbase_file_init(handle, path_ro, path_rw, &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-3.8.1/src/interfaces_local.c000066400000000000000000000036741476211737200202460ustar00rootroot00000000000000/* 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-3.8.1/src/interfaces_policy.c000066400000000000000000000026701476211737200204460ustar00rootroot00000000000000/* 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-3.8.1/src/interfaces_policydb.c000066400000000000000000000043561476211737200207570ustar00rootroot00000000000000/* * 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" #include "semanage_store.h" /* INTERFACE RECRORD (SEPOL): POLICYDB extension: method table */ static const 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, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL), semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), &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-3.8.1/src/libsemanage.map000066400000000000000000000244731476211737200175530ustar00rootroot00000000000000LIBSEMANAGE_1.0 { global: semanage_access_check; semanage_begin_transaction; semanage_bool_clone; semanage_bool_compare; semanage_bool_compare2; semanage_bool_count; semanage_bool_count_active; semanage_bool_count_local; semanage_bool_create; semanage_bool_del_local; semanage_bool_exists; semanage_bool_exists_active; semanage_bool_exists_local; semanage_bool_free; semanage_bool_get_name; semanage_bool_get_value; semanage_bool_iterate; semanage_bool_iterate_active; semanage_bool_iterate_local; semanage_bool_key_create; semanage_bool_key_extract; semanage_bool_key_free; semanage_bool_list; semanage_bool_list_active; semanage_bool_list_local; semanage_bool_modify_local; semanage_bool_query; semanage_bool_query_active; semanage_bool_query_local; semanage_bool_set_active; semanage_bool_set_name; semanage_bool_set_value; semanage_commit; semanage_connect; semanage_context_clone; semanage_context_create; semanage_context_free; semanage_context_from_string; semanage_context_get_mls; semanage_context_get_role; semanage_context_get_type; semanage_context_get_user; semanage_context_set_mls; semanage_context_set_role; semanage_context_set_type; semanage_context_set_user; semanage_context_to_string; semanage_disconnect; semanage_fcontext_clone; semanage_fcontext_compare; semanage_fcontext_compare2; semanage_fcontext_count; semanage_fcontext_count_local; semanage_fcontext_create; semanage_fcontext_del_local; semanage_fcontext_exists; semanage_fcontext_exists_local; semanage_fcontext_free; semanage_fcontext_get_con; semanage_fcontext_get_expr; semanage_fcontext_get_type; semanage_fcontext_get_type_str; semanage_fcontext_iterate; semanage_fcontext_iterate_local; semanage_fcontext_key_create; semanage_fcontext_key_extract; semanage_fcontext_key_free; semanage_fcontext_list; semanage_fcontext_list_homedirs; semanage_fcontext_list_local; semanage_fcontext_modify_local; semanage_fcontext_query; semanage_fcontext_query_local; semanage_fcontext_set_con; semanage_fcontext_set_expr; semanage_fcontext_set_type; semanage_get_disable_dontaudit; semanage_get_preserve_tunables; semanage_handle_create; semanage_handle_destroy; semanage_ibendport_clone; semanage_ibendport_compare; semanage_ibendport_compare2; semanage_ibendport_count; semanage_ibendport_count_local; semanage_ibendport_create; semanage_ibendport_del_local; semanage_ibendport_exists; semanage_ibendport_exists_local; semanage_ibendport_free; semanage_ibendport_get_con; semanage_ibendport_get_ibdev_name; semanage_ibendport_get_port; semanage_ibendport_iterate; semanage_ibendport_iterate_local; semanage_ibendport_key_create; semanage_ibendport_key_extract; semanage_ibendport_key_free; semanage_ibendport_list; semanage_ibendport_list_local; semanage_ibendport_modify_local; semanage_ibendport_query; semanage_ibendport_query_local; semanage_ibendport_set_con; semanage_ibendport_set_ibdev_name; semanage_ibendport_set_port; semanage_ibpkey_clone; semanage_ibpkey_compare; semanage_ibpkey_compare2; semanage_ibpkey_count; semanage_ibpkey_count_local; semanage_ibpkey_create; semanage_ibpkey_del_local; semanage_ibpkey_exists; semanage_ibpkey_exists_local; semanage_ibpkey_free; semanage_ibpkey_get_con; semanage_ibpkey_get_high; semanage_ibpkey_get_low; semanage_ibpkey_get_subnet_prefix; semanage_ibpkey_get_subnet_prefix_bytes; semanage_ibpkey_iterate; semanage_ibpkey_iterate_local; semanage_ibpkey_key_create; semanage_ibpkey_key_extract; semanage_ibpkey_key_free; semanage_ibpkey_list; semanage_ibpkey_list_local; semanage_ibpkey_modify_local; semanage_ibpkey_query; semanage_ibpkey_query_local; semanage_ibpkey_set_con; semanage_ibpkey_set_pkey; semanage_ibpkey_set_range; semanage_ibpkey_set_subnet_prefix; semanage_ibpkey_set_subnet_prefix_bytes; semanage_iface_clone; semanage_iface_compare; semanage_iface_compare2; semanage_iface_count; semanage_iface_count_local; semanage_iface_create; semanage_iface_del_local; semanage_iface_exists; semanage_iface_exists_local; semanage_iface_free; semanage_iface_get_ifcon; semanage_iface_get_msgcon; semanage_iface_get_name; semanage_iface_iterate; semanage_iface_iterate_local; semanage_iface_key_create; semanage_iface_key_extract; semanage_iface_key_free; semanage_iface_list; semanage_iface_list_local; semanage_iface_modify_local; semanage_iface_query; semanage_iface_query_local; semanage_iface_set_ifcon; semanage_iface_set_msgcon; semanage_iface_set_name; semanage_is_connected; semanage_is_managed; semanage_mls_enabled; semanage_module_get_name; semanage_module_get_version; semanage_module_info_datum_destroy; semanage_module_install_file; semanage_module_list; semanage_module_list_nth; semanage_module_remove; semanage_module_upgrade_file; semanage_msg_get_channel; semanage_msg_get_fname; semanage_msg_get_level; semanage_msg_set_callback; semanage_node_clone; semanage_node_compare; semanage_node_compare2; semanage_node_count; semanage_node_count_local; semanage_node_create; semanage_node_del_local; semanage_node_exists; semanage_node_exists_local; semanage_node_free; semanage_node_get_addr; semanage_node_get_addr_bytes; semanage_node_get_con; semanage_node_get_mask; semanage_node_get_mask_bytes; semanage_node_get_proto; semanage_node_get_proto_str; semanage_node_iterate; semanage_node_iterate_local; semanage_node_key_create; semanage_node_key_extract; semanage_node_key_free; semanage_node_list; semanage_node_list_local; semanage_node_modify_local; semanage_node_query; semanage_node_query_local; semanage_node_set_addr; semanage_node_set_addr_bytes; semanage_node_set_con; semanage_node_set_mask; semanage_node_set_mask_bytes; semanage_node_set_proto; semanage_port_clone; semanage_port_compare; semanage_port_compare2; semanage_port_count; semanage_port_count_local; semanage_port_create; semanage_port_del_local; semanage_port_exists; semanage_port_exists_local; semanage_port_free; semanage_port_get_con; semanage_port_get_high; semanage_port_get_low; semanage_port_get_proto; semanage_port_get_proto_str; semanage_port_iterate; semanage_port_iterate_local; semanage_port_key_create; semanage_port_key_extract; semanage_port_key_free; semanage_port_list; semanage_port_list_local; semanage_port_modify_local; semanage_port_query; semanage_port_query_local; semanage_port_set_con; semanage_port_set_port; semanage_port_set_proto; semanage_port_set_range; semanage_reload_policy; semanage_root; semanage_select_store; semanage_set_check_contexts; semanage_set_create_store; semanage_set_disable_dontaudit; semanage_set_preserve_tunables; semanage_set_rebuild; semanage_set_reload; semanage_set_root; semanage_seuser_clone; semanage_seuser_compare; semanage_seuser_compare2; semanage_seuser_count; semanage_seuser_count_local; semanage_seuser_create; semanage_seuser_del_local; semanage_seuser_exists; semanage_seuser_exists_local; semanage_seuser_free; semanage_seuser_get_mlsrange; semanage_seuser_get_name; semanage_seuser_get_sename; semanage_seuser_iterate; semanage_seuser_iterate_local; semanage_seuser_key_create; semanage_seuser_key_extract; semanage_seuser_key_free; semanage_seuser_list; semanage_seuser_list_local; semanage_seuser_modify_local; semanage_seuser_query; semanage_seuser_query_local; semanage_seuser_set_mlsrange; semanage_seuser_set_name; semanage_seuser_set_sename; semanage_user_add_role; semanage_user_clone; semanage_user_compare; semanage_user_compare2; semanage_user_count; semanage_user_count_local; semanage_user_create; semanage_user_del_local; semanage_user_del_role; semanage_user_exists; semanage_user_exists_local; semanage_user_free; semanage_user_get_mlslevel; semanage_user_get_mlsrange; semanage_user_get_name; semanage_user_get_num_roles; semanage_user_get_prefix; semanage_user_get_roles; semanage_user_has_role; semanage_user_iterate; semanage_user_iterate_local; semanage_user_key_create; semanage_user_key_extract; semanage_user_key_free; semanage_user_list; semanage_user_list_local; semanage_user_modify_local; semanage_user_query; semanage_user_query_local; semanage_user_set_mlslevel; semanage_user_set_mlsrange; semanage_user_set_name; semanage_user_set_prefix; semanage_user_set_roles; local: *; }; LIBSEMANAGE_1.1 { global: semanage_module_install; semanage_module_extract; semanage_get_hll_compiler_path; semanage_get_ignore_module_cache; semanage_set_ignore_module_cache; semanage_get_default_priority; semanage_set_default_priority; semanage_module_info_create; semanage_module_info_destroy; semanage_module_info_get_priority; semanage_module_info_get_name; semanage_module_info_get_lang_ext; semanage_module_info_get_enabled; semanage_module_info_set_priority; semanage_module_info_set_name; semanage_module_info_set_lang_ext; semanage_module_info_set_enabled; semanage_module_key_create; semanage_module_key_destroy; semanage_module_key_get_priority; semanage_module_key_get_name; semanage_module_key_set_priority; semanage_module_key_set_name; semanage_module_get_module_info; semanage_module_list_all; semanage_module_get_enabled; semanage_module_set_enabled; semanage_module_install_info; semanage_module_remove_key; semanage_set_store_root; } LIBSEMANAGE_1.0; LIBSEMANAGE_3.4 { semanage_module_compute_checksum; semanage_set_check_ext_changes; } LIBSEMANAGE_1.1; libsemanage-3.8.1/src/libsemanage.pc.in000066400000000000000000000004651476211737200200000ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ Name: libsemanage Description: SELinux management library Version: @VERSION@ URL: http://userspace.selinuxproject.org/ Requires.private: libselinux libsepol Libs: -L${libdir} -lsemanage Libs.private: -lbz2 Cflags: -I${includedir} libsemanage-3.8.1/src/modules.c000066400000000000000000000521541476211737200164160ustar00rootroot00000000000000/* Author: Joshua Brindle * Caleb Case * * Copyright (C) 2004-2005,2009 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 "modules.h" #include "semanage_conf.h" #include "semanage_store.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "handle.h" #include "sha256.h" #include "debug.h" int semanage_module_install(semanage_handle_t * sh, char *module_data, size_t data_len, const char *name, const char *ext_lang) { 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, name, ext_lang); } 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_extract(semanage_handle_t * sh, semanage_module_key_t *modkey, int extract_cil, void **mapped_data, size_t *data_len, semanage_module_info_t **modinfo) { if (sh->funcs->extract == NULL) { ERR(sh, "No get function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } return sh->funcs->extract(sh, modkey, extract_cil, mapped_data, data_len, modinfo); } /* Legacy function that remains to preserve ABI * compatibility. Please use semanage_module_install_file instead. */ int semanage_module_upgrade_file(semanage_handle_t * sh, const char *module_name) { return semanage_module_install_file(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) { modinfo->priority = 0; free(modinfo->name); modinfo->name = NULL; free(modinfo->lang_ext); modinfo->lang_ext = NULL; modinfo->enabled = -1; } } semanage_module_info_t *semanage_module_list_nth(semanage_module_info_t * list, int n) { return list + n; } const char *semanage_module_get_name(semanage_module_info_t * modinfo) { return modinfo->name; } /* Legacy function that remains to preserve ABI * compatibility. */ extern const char *semanage_module_get_version(semanage_module_info_t *); const char *semanage_module_get_version(semanage_module_info_t * modinfo __attribute__ ((unused))) { return ""; } int semanage_module_info_create(semanage_handle_t *sh, semanage_module_info_t **modinfo) { assert(sh); assert(modinfo); *modinfo = malloc(sizeof(semanage_module_info_t)); if (*modinfo == NULL) return -1; return semanage_module_info_init(sh, *modinfo); } int semanage_module_info_destroy(semanage_handle_t *sh, semanage_module_info_t *modinfo) { assert(sh); if (!modinfo) { return 0; } free(modinfo->name); free(modinfo->lang_ext); return semanage_module_info_init(sh, modinfo); } int semanage_module_info_init(semanage_handle_t *sh, semanage_module_info_t *modinfo) { assert(sh); assert(modinfo); modinfo->priority = 0; modinfo->name = NULL; modinfo->lang_ext = NULL; modinfo->enabled = -1; return 0; } int semanage_module_info_clone(semanage_handle_t *sh, const semanage_module_info_t *source, semanage_module_info_t *target) { assert(sh); assert(source); assert(target); int status = 0; int ret = 0; ret = semanage_module_info_destroy(sh, target); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_set_priority(sh, target, source->priority); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_set_name(sh, target, source->name); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_set_lang_ext(sh, target, source->lang_ext); if (ret != 0) { status = -1; goto cleanup; } ret = semanage_module_info_set_enabled(sh, target, source->enabled); if (ret != 0) { status = -1; goto cleanup; } cleanup: if (status != 0) semanage_module_info_destroy(sh, target); return status; } int semanage_module_info_get_priority(semanage_handle_t *sh, semanage_module_info_t *modinfo, uint16_t *priority) { assert(sh); assert(modinfo); assert(priority); *priority = modinfo->priority; return 0; } int semanage_module_info_get_name(semanage_handle_t *sh, semanage_module_info_t *modinfo, const char **name) { assert(sh); assert(modinfo); assert(name); *name = modinfo->name; return 0; } int semanage_module_info_get_lang_ext(semanage_handle_t *sh, semanage_module_info_t *modinfo, const char **lang_ext) { assert(sh); assert(modinfo); assert(lang_ext); *lang_ext = modinfo->lang_ext; return 0; } int semanage_module_info_get_enabled(semanage_handle_t *sh, semanage_module_info_t *modinfo, int *enabled) { assert(sh); assert(modinfo); assert(enabled); *enabled = modinfo->enabled; return 0; } int semanage_module_info_set_priority(semanage_handle_t *sh, semanage_module_info_t *modinfo, uint16_t priority) { assert(sh); assert(modinfo); /* Verify priority */ if (semanage_module_validate_priority(priority) < 0) { errno = 0; ERR(sh, "Priority %d is invalid.", priority); return -1; } modinfo->priority = priority; return 0; } int semanage_module_info_set_name(semanage_handle_t *sh, semanage_module_info_t *modinfo, const char *name) { assert(sh); assert(modinfo); assert(name); char * tmp; /* Verify name */ if (semanage_module_validate_name(name) < 0) { errno = 0; ERR(sh, "Name %s is invalid.", name); return -1; } tmp = strdup(name); if (!tmp) { ERR(sh, "No memory available for strdup"); return -1; } free(modinfo->name); modinfo->name = tmp; return 0; } int semanage_module_info_set_lang_ext(semanage_handle_t *sh, semanage_module_info_t *modinfo, const char *lang_ext) { assert(sh); assert(modinfo); assert(lang_ext); char * tmp; /* Verify extension */ if (semanage_module_validate_lang_ext(lang_ext) < 0) { errno = 0; ERR(sh, "Language extensions %s is invalid.", lang_ext); return -1; } tmp = strdup(lang_ext); if (!tmp) { ERR(sh, "No memory available for strdup"); return -1; } free(modinfo->lang_ext); modinfo->lang_ext = tmp; return 0; } int semanage_module_info_set_enabled(semanage_handle_t *sh, semanage_module_info_t *modinfo, int enabled) { assert(sh); assert(modinfo); /* Verify enabled */ if (semanage_module_validate_enabled(enabled) < 0) { errno = 0; ERR(sh, "Enabled status %d is invalid.", enabled); return -1; } modinfo->enabled = enabled; return 0; } int semanage_module_get_path(semanage_handle_t *sh, const semanage_module_info_t *modinfo, enum semanage_module_path_type type, char *path, size_t len) { assert(sh); assert(modinfo); assert(path); int status = 0; int ret = 0; const char *modules_path = NULL; const char *file = NULL; modules_path = sh->is_in_transaction ? semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES): semanage_path(SEMANAGE_ACTIVE, SEMANAGE_MODULES); switch (type) { case SEMANAGE_MODULE_PATH_PRIORITY: /* verify priority */ ret = semanage_module_validate_priority(modinfo->priority); if (ret < 0) { errno = 0; ERR(sh, "Priority %d is invalid.", modinfo->priority); status = ret; goto cleanup; } ret = snprintf(path, len, "%s/%03u", modules_path, modinfo->priority); if (ret < 0 || (size_t)ret >= len) { ERR(sh, "Unable to compose priority path."); status = -1; goto cleanup; } break; case SEMANAGE_MODULE_PATH_NAME: /* verify priority and name */ ret = semanage_module_validate_priority(modinfo->priority); if (ret < 0) { errno = 0; ERR(sh, "Priority %d is invalid.", modinfo->priority); status = -1; goto cleanup; } ret = semanage_module_validate_name(modinfo->name); if (ret < 0) { errno = 0; ERR(sh, "Name %s is invalid.", modinfo->name); status = -1; goto cleanup; } ret = snprintf(path, len, "%s/%03u/%s", modules_path, modinfo->priority, modinfo->name); if (ret < 0 || (size_t)ret >= len) { ERR(sh, "Unable to compose name path."); status = -1; goto cleanup; } break; case SEMANAGE_MODULE_PATH_HLL: if (file == NULL) file = "hll"; /* FALLTHRU */ case SEMANAGE_MODULE_PATH_CIL: if (file == NULL) file = "cil"; /* FALLTHRU */ case SEMANAGE_MODULE_PATH_LANG_EXT: if (file == NULL) file = "lang_ext"; /* verify priority and name */ ret = semanage_module_validate_priority(modinfo->priority); if (ret < 0) { errno = 0; ERR(sh, "Priority %d is invalid.", modinfo->priority); status = -1; goto cleanup; } ret = semanage_module_validate_name(modinfo->name); if (ret < 0) { errno = 0; ERR(sh, "Name %s is invalid.", modinfo->name); status = -1; goto cleanup; } ret = snprintf(path, len, "%s/%03u/%s/%s", modules_path, modinfo->priority, modinfo->name, file); if (ret < 0 || (size_t)ret >= len) { ERR(sh, "Unable to compose path for %s file.", file); status = -1; goto cleanup; } break; case SEMANAGE_MODULE_PATH_DISABLED: /* verify name */ ret = semanage_module_validate_name(modinfo->name); if (ret < 0) { errno = 0; ERR(sh, "Name %s is invalid.", modinfo->name); status = -1; goto cleanup; } ret = snprintf(path, len, "%s/disabled/%s", modules_path, modinfo->name); if (ret < 0 || (size_t)ret >= len) { ERR(sh, "Unable to compose disabled status path."); status = -1; goto cleanup; } break; default: ERR(sh, "Invalid module path type %d.", type); status = -1; goto cleanup; } cleanup: return status; } int semanage_module_key_create(semanage_handle_t *sh, semanage_module_key_t **modkey) { assert(sh); assert(modkey); *modkey = malloc(sizeof(semanage_module_key_t)); if (*modkey == NULL) return -1; return semanage_module_key_init(sh, *modkey); } int semanage_module_key_destroy(semanage_handle_t *sh, semanage_module_key_t *modkey) { assert(sh); if (!modkey) { return 0; } free(modkey->name); return semanage_module_key_init(sh, modkey); } int semanage_module_key_init(semanage_handle_t *sh, semanage_module_key_t *modkey) { assert(sh); assert(modkey); modkey->name = NULL; modkey->priority = 0; return 0; } int semanage_module_key_get_name(semanage_handle_t *sh, semanage_module_key_t *modkey, const char **name) { assert(sh); assert(modkey); assert(name); *name = modkey->name; return 0; } int semanage_module_key_get_priority(semanage_handle_t *sh, semanage_module_key_t *modkey, uint16_t *priority) { assert(sh); assert(modkey); assert(priority); *priority = modkey->priority; return 0; } int semanage_module_key_set_name(semanage_handle_t *sh, semanage_module_key_t *modkey, const char *name) { assert(sh); assert(modkey); assert(name); int status = 0; char *tmp = NULL; if (semanage_module_validate_name(name) < 0) { errno = 0; ERR(sh, "Name %s is invalid.", name); return -1; } tmp = strdup(name); if (tmp == NULL) { ERR(sh, "No memory available for strdup"); status = -1; goto cleanup; } free(modkey->name); modkey->name = tmp; cleanup: return status; } int semanage_module_key_set_priority(semanage_handle_t *sh, semanage_module_key_t *modkey, uint16_t priority) { assert(sh); assert(modkey); if (semanage_module_validate_priority(priority) < 0) { errno = 0; ERR(sh, "Priority %d is invalid.", priority); return -1; } modkey->priority = priority; return 0; } int semanage_module_get_enabled(semanage_handle_t *sh, const semanage_module_key_t *modkey, int *enabled) { assert(sh); assert(modkey); assert(enabled); if (sh->funcs->get_enabled == NULL) { ERR(sh, "No get_enabled function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } return sh->funcs->get_enabled(sh, modkey, enabled); } int semanage_module_set_enabled(semanage_handle_t *sh, const semanage_module_key_t *modkey, int enabled) { assert(sh); assert(modkey); if (sh->funcs->set_enabled == NULL) { ERR(sh, "No set_enabled 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->set_enabled(sh, modkey, enabled); } /* Converts a string to a priority * * returns -1 if str is not a valid priority. * returns 0 and sets priority if str is a valid priority */ int semanage_string_to_priority(const char *str, uint16_t *priority) { unsigned long val; char *endptr = NULL; int status = -1; if (str == NULL || priority == NULL) { goto exit; } errno = 0; val = strtoul(str, &endptr, 10); if (errno != 0 || endptr == str || *endptr != '\0' || val > UINT16_MAX) { goto exit; } if (semanage_module_validate_priority((uint16_t)val) < 0) { goto exit; } *priority = val; status = 0; exit: return status; } /* Validates a module info struct. * * Returns -1 if module is invalid, 0 otherwise. */ int semanage_module_info_validate(const semanage_module_info_t *modinfo) { if (semanage_module_validate_priority(modinfo->priority) != 0 || semanage_module_validate_name(modinfo->name) != 0 || semanage_module_validate_lang_ext(modinfo->lang_ext) != 0 || semanage_module_validate_enabled(modinfo->enabled) != 0) { return -1; } return 0; } #define PRIORITY_MIN 1 #define PRIORITY_MAX 999 /* Validates priority. * * returns -1 if priority is not in the valid range, returns 0 otherwise */ int semanage_module_validate_priority(uint16_t priority) { if (priority >= PRIORITY_MIN && priority <= PRIORITY_MAX) { return 0; } return -1; } /* Validates module name. * * A module name must match one of the following regular expressions * to be considered valid: * * ^[a-zA-Z](\.?[a-zA-Z0-9_-])*$ * * returns -1 if name is not valid, returns 0 otherwise */ int semanage_module_validate_name(const char * name) { int status = 0; if (name == NULL) { status = -1; goto exit; } if (!isalpha((unsigned char)*name)) { status = -1; goto exit; } #define ISVALIDCHAR(c) (isalnum((unsigned char)c) || c == '_' || c == '-') for (name++; *name; name++) { if (ISVALIDCHAR(*name)) { continue; } if (*name == '.' && name++ && ISVALIDCHAR(*name)) { continue; } status = -1; goto exit; } #undef ISVALIDCHAR exit: return status; } /* Validates module enabled status. * * Valid enabled values are 1, 0, and -1. * * returns 0 if enabled is a valid value, returns -1 otherwise. */ int semanage_module_validate_enabled(int enabled) { if (enabled == 1 || enabled == 0 || enabled == -1) { return 0; } return -1; } /* Validate extension. * * An extension must match the following regular expression to be * considered valid: * * ^[a-zA-Z0-9][a-zA-Z0-9_-]*$ * * returns 0 if ext is a valid value, returns -1 otherwise. */ int semanage_module_validate_lang_ext(const char *ext) { int status = 0; if (ext == NULL) { status = -1; goto exit; } if (!isalnum((unsigned char)*ext)) { status = -1; goto exit; } #define ISVALIDCHAR(c) (isalnum((unsigned char)c) || c == '_' || c == '-') for (ext++; *ext; ext++) { if (ISVALIDCHAR(*ext)) { continue; } status = -1; goto exit; } #undef ISVALIDCHAR exit: return status; } int semanage_module_get_module_info(semanage_handle_t *sh, const semanage_module_key_t *modkey, semanage_module_info_t **modinfo) { assert(sh); assert(modkey); assert(modinfo); if (sh->funcs->get_module_info == NULL) { ERR(sh, "No get module info function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } return sh->funcs->get_module_info(sh, modkey, modinfo); } int semanage_module_list_all(semanage_handle_t *sh, semanage_module_info_t **modinfos, int *modinfos_len) { assert(sh); assert(modinfos); assert(modinfos_len); if (sh->funcs->list_all == NULL) { ERR(sh, "No list all function defined for this connection type."); return -1; } else if (!sh->is_connected) { ERR(sh, "Not connected."); return -1; } return sh->funcs->list_all(sh, modinfos, modinfos_len); } int semanage_module_install_info(semanage_handle_t *sh, const semanage_module_info_t *modinfo, char *data, size_t data_len) { if (sh->funcs->install_info == NULL) { ERR(sh, "No install info 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_info(sh, modinfo, data, data_len); } int semanage_module_remove_key(semanage_handle_t *sh, const semanage_module_key_t *modkey) { if (sh->funcs->remove_key == NULL) { ERR(sh, "No remove key 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_key(sh, modkey); } static const char CHECKSUM_TYPE[] = "sha256"; const size_t CHECKSUM_CONTENT_SIZE = sizeof(CHECKSUM_TYPE) + 1 + 2 * SHA256_HASH_SIZE; void semanage_hash_to_checksum_string(const uint8_t *hash, char *checksum) { size_t i; checksum += sprintf(checksum, "%s:", CHECKSUM_TYPE); for (i = 0; i < SHA256_HASH_SIZE; i++) { checksum += sprintf(checksum, "%02x", (unsigned)hash[i]); } } int semanage_module_compute_checksum(semanage_handle_t *sh, semanage_module_key_t *modkey, int cil, char **checksum, size_t *checksum_len) { semanage_module_info_t *extract_info = NULL; SHA256_HASH sha256_hash; char *checksum_str; void *data; size_t data_len = 0; int result; if (!checksum_len) return -1; if (!checksum) { *checksum_len = CHECKSUM_CONTENT_SIZE; return 0; } result = semanage_module_extract(sh, modkey, cil, &data, &data_len, &extract_info); if (result != 0) return -1; semanage_module_info_destroy(sh, extract_info); free(extract_info); Sha256Calculate(data, data_len, &sha256_hash); munmap(data, data_len); checksum_str = malloc(CHECKSUM_CONTENT_SIZE + 1 /* '\0' */); if (!checksum_str) return -1; semanage_hash_to_checksum_string(sha256_hash.bytes, checksum_str); *checksum = checksum_str; *checksum_len = CHECKSUM_CONTENT_SIZE; return 0; } libsemanage-3.8.1/src/modules.h000066400000000000000000000065431476211737200164240ustar00rootroot00000000000000/* Author: Joshua Brindle * Jason Tang * Caleb Case * * Copyright (C) 2005,2009 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 #include "semanage/modules.h" int semanage_module_upgrade_file(semanage_handle_t * sh, const char *module_name); int semanage_module_install_base_file(semanage_handle_t * sh, const char *module_name); /* Module Info */ struct semanage_module_info { uint16_t priority; /* key, module priority */ char *name; /* key, module name */ char *lang_ext; /* module source language extension */ int enabled; /* module enabled/disabled status */ }; /* Initializes a pre-allocated module info struct. * * Returns 0 on success and -1 on error. */ int semanage_module_info_init(semanage_handle_t *sh, semanage_module_info_t *modinfo); /* Clones module info @source's members into module info @target. * * Returns 0 on success and -1 on error. */ int semanage_module_info_clone(semanage_handle_t *sh, const semanage_module_info_t *source, semanage_module_info_t *target); /* Convert a cstring to a priority. * * Returns 0 on success and -1 on error. */ int semanage_string_to_priority(const char *str, uint16_t *priority); int semanage_module_info_validate(const semanage_module_info_t *modinfo); int semanage_module_validate_priority(uint16_t priority); int semanage_module_validate_name(const char *name); int semanage_module_validate_enabled(int enabled); int semanage_module_validate_lang_ext(const char *ext); int semanage_module_validate_version(const char *version); /* Module Key */ struct semanage_module_key { uint16_t priority; /* module priority */ char *name; /* module name */ }; /* Initializes a pre-allocated module key struct. * * Returns 0 on success, and -1 on error. */ int semanage_module_key_init(semanage_handle_t *sh, semanage_module_key_t *modkey); /* Module Paths */ enum semanage_module_path_type { SEMANAGE_MODULE_PATH_PRIORITY, SEMANAGE_MODULE_PATH_NAME, SEMANAGE_MODULE_PATH_HLL, SEMANAGE_MODULE_PATH_CIL, SEMANAGE_MODULE_PATH_LANG_EXT, SEMANAGE_MODULE_PATH_DISABLED, }; /* Get the module path for the given path @type. * * Returns 0 on success and -1 on error. */ int semanage_module_get_path(semanage_handle_t *sh, const semanage_module_info_t *module, enum semanage_module_path_type type, char *path, size_t len); extern const size_t CHECKSUM_CONTENT_SIZE; void semanage_hash_to_checksum_string(const uint8_t *hash, char *checksum); #endif libsemanage-3.8.1/src/node_internal.h000066400000000000000000000015331476211737200175670ustar00rootroot00000000000000#ifndef _SEMANAGE_NODE_INTERNAL_H_ #define _SEMANAGE_NODE_INTERNAL_H_ #include #include #include #include "database.h" #include "handle.h" /* NODE RECORD: method table */ extern const record_table_t SEMANAGE_NODE_RTABLE; extern int node_file_dbase_init(semanage_handle_t * handle, const char *path_ro, const char *path_rw, 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 semanage_node_validate_local(semanage_handle_t * handle); /* ==== Internal (to nodes) API === */ int semanage_node_compare2_qsort(const void *p1, const void *p2); #endif libsemanage-3.8.1/src/node_record.c000066400000000000000000000112051476211737200172210ustar00rootroot00000000000000/* 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); } int semanage_node_compare2(const semanage_node_t * node, const semanage_node_t * node2) { return sepol_node_compare2(node, node2); } int semanage_node_compare2_qsort(const void *p1, const void *p2) { const semanage_node_t *const *node1 = p1; const semanage_node_t *const *node2 = p2; return sepol_node_compare2(*node1, *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); } void semanage_node_key_free(semanage_node_key_t * key) { sepol_node_key_free(key); } /* 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); } 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); } 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); } 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); } /* 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); } 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); } 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); } 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); } /* Protocol */ int semanage_node_get_proto(const semanage_node_t * node) { return sepol_node_get_proto(node); } void semanage_node_set_proto(semanage_node_t * node, int proto) { sepol_node_set_proto(node, proto); } const char *semanage_node_get_proto_str(int proto) { return sepol_node_get_proto_str(proto); } /* Context */ semanage_context_t *semanage_node_get_con(const semanage_node_t * node) { return sepol_node_get_con(node); } 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); } /* Create/Clone/Destroy */ int semanage_node_create(semanage_handle_t * handle, semanage_node_t ** node_ptr) { return sepol_node_create(handle->sepolh, node_ptr); } 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); } void semanage_node_free(semanage_node_t * node) { sepol_node_free(node); } /* Port base functions */ const 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-3.8.1/src/nodes_file.c000066400000000000000000000100311476211737200170410ustar00rootroot00000000000000/* 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 "database_file.h" #include "parse_utils.h" #include "debug.h" static int node_print(semanage_handle_t * handle, const 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) < 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) < 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) < 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) < 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 */ static const 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 *path_ro, const char *path_rw, dbase_config_t * dconfig) { if (dbase_file_init(handle, path_ro, path_rw, &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-3.8.1/src/nodes_local.c000066400000000000000000000036501476211737200172250ustar00rootroot00000000000000/* 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); } libsemanage-3.8.1/src/nodes_policy.c000066400000000000000000000026451476211737200174350ustar00rootroot00000000000000/* 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-3.8.1/src/nodes_policydb.c000066400000000000000000000043241476211737200177370ustar00rootroot00000000000000/* * 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" #include "semanage_store.h" /* NODE RECORD (SEPOL): POLICYDB extension : method table */ static const 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, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL), semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), &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-3.8.1/src/parse_utils.c000066400000000000000000000140251476211737200172730ustar00rootroot00000000000000/* 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, "re"); if (!info->file_stream && (errno != ENOENT)) { ERR(handle, "could not open file %s.", info->filename); 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; unsigned int lineno = info->lineno; char *buffer = NULL; char *ptr; if (info->ptr) { while (*(info->ptr) && isspace((unsigned char)*(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((unsigned char)*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((unsigned char)*(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) < 0) goto err; if (!isdigit((unsigned char)*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, int allow_spaces) { const char *start = info->ptr; size_t len = 0; char *tmp_str = NULL; if (parse_assert_noeof(handle, info) < 0) goto err; while (*(info->ptr) && (allow_spaces || !isspace((unsigned char)*(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 = strndup(start, len); if (!tmp_str) { ERR(handle, "out of memory"); goto err; } *str = tmp_str; return STATUS_SUCCESS; err: ERR(handle, "could not fetch string value"); return STATUS_ERR; } libsemanage-3.8.1/src/parse_utils.h000066400000000000000000000053271476211737200173050ustar00rootroot00000000000000/* 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, 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, 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 and move the read pointer past it. * Stop if the optional character delim (or eof) is encountered, * or if whitespace is encountered and allow_spaces is 0. * 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, int allow_spaces); #endif libsemanage-3.8.1/src/policy.h000066400000000000000000000062311476211737200162450ustar00rootroot00000000000000/* 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 failure */ 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, const char *, const char *); /* Install a policy module */ int (*install_file) (struct semanage_handle *, const char *); /* Extract a policy module */ int (*extract) (struct semanage_handle *, semanage_module_key_t *, int extract_cil, void **, size_t *, semanage_module_info_t **); /* Remove a policy module */ int (*remove) (struct semanage_handle *, char *); /* List policy modules */ int (*list) (struct semanage_handle *, semanage_module_info_t **, int *); /* Get module enabled status */ int (*get_enabled) (struct semanage_handle *sh, const semanage_module_key_t *key, int *enabled); /* Set module enabled status */ int (*set_enabled) (struct semanage_handle *sh, const semanage_module_key_t *key, int enabled); /* Get a module info */ int (*get_module_info) (struct semanage_handle *, const semanage_module_key_t *, semanage_module_info_t **); /* List all policy modules */ int (*list_all) (struct semanage_handle *, semanage_module_info_t **, int *); /* Install via module info */ int (*install_info) (struct semanage_handle *, const semanage_module_info_t *, char *, size_t); /* Remove via module key */ int (*remove_key) (struct semanage_handle *, const semanage_module_key_t *); }; /* 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-3.8.1/src/policy_components.c000066400000000000000000000136601476211737200205110ustar00rootroot00000000000000/* 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; const dbase_table_t *src_dtable = src->dtable; const dbase_table_t *dst_dtable = dst->dtable; const 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; const dbase_table_t *dtable = dst->dtable; const 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 */ const 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}, {semanage_ibpkey_dbase_local(handle), semanage_ibpkey_dbase_policy(handle), MODE_MODIFY}, {semanage_ibendport_dbase_local(handle), semanage_ibendport_dbase_policy(handle), MODE_MODIFY}, }; 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; const 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) && nrecords > 1) { qsort(records, nrecords, sizeof(record_t *), 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; const 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), semanage_ibpkey_dbase_local(handle), semanage_ibendport_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-3.8.1/src/port_internal.h000066400000000000000000000015331476211737200176260ustar00rootroot00000000000000#ifndef _SEMANAGE_PORT_INTERNAL_H_ #define _SEMANAGE_PORT_INTERNAL_H_ #include #include #include #include "database.h" #include "handle.h" /* PORT RECORD: method table */ extern const record_table_t SEMANAGE_PORT_RTABLE; extern int port_file_dbase_init(semanage_handle_t * handle, const char *path_ro, const char *path_rw, 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 semanage_port_validate_local(semanage_handle_t * handle); /* ==== Internal (to ports) API === */ int semanage_port_compare2_qsort(const void* p1, const void *p2); #endif libsemanage-3.8.1/src/port_record.c000066400000000000000000000067211476211737200172670ustar00rootroot00000000000000/* 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); } int semanage_port_compare2(const semanage_port_t * port, const semanage_port_t * port2) { return sepol_port_compare2(port, port2); } int semanage_port_compare2_qsort(const void *p1, const void *p2) { const semanage_port_t *const * port1 = p1; const semanage_port_t *const * port2 = p2; return sepol_port_compare2(*port1, *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); } void semanage_port_key_free(semanage_port_key_t * key) { sepol_port_key_free(key); } /* Protocol */ int semanage_port_get_proto(const semanage_port_t * port) { return sepol_port_get_proto(port); } void semanage_port_set_proto(semanage_port_t * port, int proto) { sepol_port_set_proto(port, proto); } const char *semanage_port_get_proto_str(int proto) { return sepol_port_get_proto_str(proto); } /* Port */ int semanage_port_get_low(const semanage_port_t * port) { return sepol_port_get_low(port); } int semanage_port_get_high(const semanage_port_t * port) { return sepol_port_get_high(port); } void semanage_port_set_port(semanage_port_t * port, int port_num) { sepol_port_set_port(port, port_num); } void semanage_port_set_range(semanage_port_t * port, int low, int high) { sepol_port_set_range(port, low, high); } /* Context */ semanage_context_t *semanage_port_get_con(const semanage_port_t * port) { return sepol_port_get_con(port); } 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); } /* Create/Clone/Destroy */ int semanage_port_create(semanage_handle_t * handle, semanage_port_t ** port_ptr) { return sepol_port_create(handle->sepolh, port_ptr); } 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); } void semanage_port_free(semanage_port_t * port) { sepol_port_free(port); } /* Port base functions */ const 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-3.8.1/src/ports_file.c000066400000000000000000000107761476211737200171200ustar00rootroot00000000000000/* 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 "database_file.h" #include "parse_utils.h" #include "debug.h" static int port_print(semanage_handle_t * handle, const 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) < 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 if (!strcasecmp(str, "dccp")) semanage_port_set_proto(port, SEMANAGE_PROTO_DCCP); else if (!strcasecmp(str, "sctp")) semanage_port_set_proto(port, SEMANAGE_PROTO_SCTP); 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) < 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 */ static const 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 *path_ro, const char *path_rw, dbase_config_t * dconfig) { if (dbase_file_init(handle, path_ro, path_rw, &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-3.8.1/src/ports_local.c000066400000000000000000000072461476211737200172710ustar00rootroot00000000000000/* 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); } int 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; if (nports > 1) qsort(ports, nports, sizeof(semanage_port_t *), 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-3.8.1/src/ports_policy.c000066400000000000000000000026451476211737200174740ustar00rootroot00000000000000/* 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-3.8.1/src/ports_policydb.c000066400000000000000000000043241476211737200177760ustar00rootroot00000000000000/* * 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" #include "semanage_store.h" /* PORT RECORD (SEPOL): POLICYDB extension : method table */ static const 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, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL), semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), &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-3.8.1/src/pywrap-test.py000066400000000000000000001365451476211737200174620ustar00rootroot00000000000000#!/usr/bin/python3 from __future__ import print_function 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: %s" % trans_cnt) print("Module list size: %s" % mlist_size) if self.verbose: print("List reference: %s" % 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: %s" % module) print("Module name: %s" % semanage.semanage_module_get_name(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): %s" % 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: %s" % seuser) print("seuser name: %s" % semanage.semanage_seuser_get_name(seuser)) print(" seuser mls range: %s" % semanage.semanage_seuser_get_mlsrange(seuser)) print(" seuser sename: %s" % 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): %s" % 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: %s" % user) print("User name: %s" % semanage.semanage_user_get_name(user)) print(" User labeling prefix: %s" % semanage.semanage_user_get_prefix(user)) print(" User mls level: %s" % semanage.semanage_user_get_mlslevel(user)) print(" User mls range: %s" % semanage.semanage_user_get_mlsrange(user)) print(" User number of roles: %s" % 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(" %s" % 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): %s" % 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: %s" % 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: %s %s Context: %s" % (range_str, proto_str, 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): %s" % 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: %s" % 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: %s [%s] Context: %s" % (expr, type_str, 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): %s" % 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: %s" % 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: %s Context: %s Message Context: %s" % (name, if_con_str, 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): %s" % 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: %s" % pbool) name = semanage.semanage_bool_get_name(pbool) value = semanage.semanage_bool_get_value(pbool) print("Boolean: %s Value: %s" % (name, 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): %s" % 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: %s" % abool) name = semanage.semanage_bool_get_name(abool) value = semanage.semanage_bool_get_value(abool) print("Active Boolean: %s Value: %s" % (name, 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): %s" % 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: %s" % 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: %s/%s (%s) Context: %s" % (addr, mask, proto_str, 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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): %s" % 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): %s" % 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): %s" % 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: %s" % 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: %s" % status) status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print("Commit status (transaction number): %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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): %s" % 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): %s" % 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): %s" % 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: %s" % 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: %s" % status) status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print("Commit status (transaction number): %s" % 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: %s-%s" % (low, high)) semanage.semanage_port_set_proto(port, semanage.SEMANAGE_PROTO_TCP) if self.verbose: print("SEPort protocol set: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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): %s" % 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): %s" % 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): %s" % 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: %s" % 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: %s" % status) status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print("Commit status (transaction number): %s" % 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: %s" % semanage.semanage_fcontext_get_expr(fcon)) semanage.semanage_fcontext_set_type(fcon, semanage.SEMANAGE_FCONTEXT_REG) if self.verbose: ftype = semanage.semanage_fcontext_get_type(fcon) print("SEFContext type set: %s" % semanage.semanage_fcontext_get_type_str(ftype)) (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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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): %s" % 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): %s" % 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): %s" % 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: %s" % 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: %s" % status) status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print("Commit status (transaction number): %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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): %s" % 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): %s" % 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): %s" % 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: %s" % 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: %s" % status) status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print("Commit status (transaction number): %s" % 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: %s" % semanage.semanage_bool_get_name(pbool)) semanage.semanage_bool_set_value(pbool, 0) if self.verbose: print("SEbool value set: %s" % semanage.semanage_bool_get_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: %s" % 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): %s" % 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): %s" % 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): %s" % 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: %s" % 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: %s" % status) status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print("Commit status (transaction number): %s" % 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: %s" % 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): %s" % 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: %s" % semanage.semanage_bool_get_name(abool)) semanage.semanage_bool_set_value(abool, 0) if self.verbose: print("SEbool value set: %s" % semanage.semanage_bool_get_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): %s" % 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: %s" % status) status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print("Commit status (transaction number): %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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: %s" % 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): %s" % 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): %s" % 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): %s" % 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: %s" % 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: %s" % status) status = semanage.semanage_commit(sh) if status < 0: raise Error("Could not commit reset transaction") print("Commit status (transaction number): %s" % 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 as 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 as err: print(err.msg, file=sys.stderr) except Status as err: print(err.msg, file=sys.stderr) except Error as err: print(err.msg, file=sys.stderr) return 2 if __name__ == "__main__": sys.exit(main()) libsemanage-3.8.1/src/semanage.conf000066400000000000000000000036101476211737200172220ustar00rootroot00000000000000# 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 '/'. # example.com:4242 # - Establish a TCP connection to a remote policy # management server at example.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 # By default, semanage will generate policies for the SELinux target. # To build policies for Xen, uncomment the following line. #target-platform = xen libsemanage-3.8.1/src/semanage_conf.h000066400000000000000000000044251476211737200175360ustar00rootroot00000000000000/* 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 */ char *compiler_directory_path; int server_port; int policyvers; /* version for server generated policies */ int target_platform; 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; int remove_hll; int ignore_module_cache; int optimize_policy; int multiple_decls; 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; char *store_root_path; } 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-3.8.1/src/semanage_store.c000066400000000000000000002274611476211737200177470ustar00rootroot00000000000000/* Authors: Karl MacMillan * Joshua Brindle * Jason Tang * Christopher Ashworth * Chris PeBenito * Caleb Case * * Copyright (C) 2004-2006,2009 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 #include #include "debug.h" #include "utilities.h" #include "compressed_file.h" #define SEMANAGE_CONF_FILE "semanage.conf" /* relative path names to enum semanage_paths to special files and * directories for the module store */ 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 int semanage_paths_initialized = 0; /* These are paths relative to the bottom of the module store */ static const char *const semanage_relative_files[SEMANAGE_NUM_FILES] = { "", "/semanage.trans.LOCK", "/semanage.read.LOCK" }; static const char *const semanage_store_paths[SEMANAGE_NUM_STORES] = { "/active", "/previous", "/tmp" }; /* relative path names to enum sandbox_paths for special files within * a sandbox */ static const char *const semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = { "", "/modules", "/policy.linked", "/homedir_template", "/file_contexts.template", "/commit_num", "/pkeys.local", "/ibendports.local", "/ports.local", "/interfaces.local", "/nodes.local", "/booleans.local", "/seusers.local", "/seusers.linked", "/users.local", "/users_extra.local", "/users_extra.linked", "/users_extra", "/disable_dontaudit", "/preserve_tunables", "/modules/disabled", "/modules_checksum", "/policy.kern", "/file_contexts.local", "/file_contexts.homedirs", "/file_contexts", "/seusers" }; static char const * const semanage_final_prefix[SEMANAGE_FINAL_NUM] = { "/final", "", }; static char *semanage_final[SEMANAGE_FINAL_NUM] = { NULL }; static char *semanage_final_suffix[SEMANAGE_FINAL_PATH_NUM] = { NULL }; static char *semanage_final_paths[SEMANAGE_FINAL_NUM][SEMANAGE_FINAL_PATH_NUM] = {{ NULL }}; /* 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; size_t path_len; size_t effective_len; size_t type_len; size_t 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) { int i; if (!root) return -1; for (i = 0; i < SEMANAGE_NUM_FILES; i++) { if (asprintf(&semanage_files[i], "%s%s", root, semanage_relative_files[i]) < 0) { semanage_files[i] = NULL; return -1; } } 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; if (!root) return -1; for (i = 0; i < SEMANAGE_NUM_STORES; i++) { for (j = 0; j < SEMANAGE_STORE_NUM_PATHS; j++) { if (asprintf(&semanage_paths[i][j], "%s%s%s", root, semanage_store_paths[i], semanage_sandbox_paths[j]) < 0) { semanage_paths[i][j] = NULL; return -1; } } } return 0; } static int semanage_init_final(semanage_handle_t *sh, const char *prefix) { assert(sh); assert(prefix); int status = 0; const char *store_path = sh->conf->store_path; /* SEMANAGE_FINAL_TMP */ if (asprintf(&semanage_final[SEMANAGE_FINAL_TMP], "%s%s%s/%s", semanage_root(), prefix, semanage_final_prefix[SEMANAGE_FINAL_TMP], store_path) < 0) { semanage_final[SEMANAGE_FINAL_TMP] = NULL; status = -1; goto cleanup; } /* SEMANAGE_FINAL_SELINUX */ if (asprintf(&semanage_final[SEMANAGE_FINAL_SELINUX], "%s%s%s%s", semanage_root(), selinux_path(), semanage_final_prefix[SEMANAGE_FINAL_SELINUX], store_path) < 0) { semanage_final[SEMANAGE_FINAL_SELINUX] = NULL; status = -1; goto cleanup; } cleanup: if (status != 0) { int i; for (i = 0; i < SEMANAGE_FINAL_NUM; i++) { free(semanage_final[i]); semanage_final[i] = NULL; } } return status; } static int semanage_init_final_suffix(semanage_handle_t *sh) { int ret = 0; int status = 0; char path[PATH_MAX]; size_t offset = strlen(selinux_policy_root()); semanage_final_suffix[SEMANAGE_FINAL_TOPLEVEL] = strdup(""); if (semanage_final_suffix[SEMANAGE_FINAL_TOPLEVEL] == NULL) { ERR(sh, "Unable to allocate space for policy top level path."); status = -1; goto cleanup; } semanage_final_suffix[SEMANAGE_FC] = strdup(selinux_file_context_path() + offset); if (semanage_final_suffix[SEMANAGE_FC] == NULL) { ERR(sh, "Unable to allocate space for file context path."); status = -1; goto cleanup; } if (asprintf(&semanage_final_suffix[SEMANAGE_FC_BIN], "%s.bin", semanage_final_suffix[SEMANAGE_FC]) < 0) { ERR(sh, "Unable to allocate space for file context path."); status = -1; goto cleanup; } semanage_final_suffix[SEMANAGE_FC_HOMEDIRS] = strdup(selinux_file_context_homedir_path() + offset); if (semanage_final_suffix[SEMANAGE_FC_HOMEDIRS] == NULL) { ERR(sh, "Unable to allocate space for file context home directory path."); status = -1; goto cleanup; } if (asprintf(&semanage_final_suffix[SEMANAGE_FC_HOMEDIRS_BIN], "%s.bin", semanage_final_suffix[SEMANAGE_FC_HOMEDIRS]) < 0) { ERR(sh, "Unable to allocate space for file context home directory path."); status = -1; goto cleanup; } semanage_final_suffix[SEMANAGE_FC_LOCAL] = strdup(selinux_file_context_local_path() + offset); if (semanage_final_suffix[SEMANAGE_FC_LOCAL] == NULL) { ERR(sh, "Unable to allocate space for local file context path."); status = -1; goto cleanup; } if (asprintf(&semanage_final_suffix[SEMANAGE_FC_LOCAL_BIN], "%s.bin", semanage_final_suffix[SEMANAGE_FC_LOCAL]) < 0) { ERR(sh, "Unable to allocate space for local file context path."); status = -1; goto cleanup; } semanage_final_suffix[SEMANAGE_NC] = strdup(selinux_netfilter_context_path() + offset); if (semanage_final_suffix[SEMANAGE_NC] == NULL) { ERR(sh, "Unable to allocate space for netfilter context path."); status = -1; goto cleanup; } semanage_final_suffix[SEMANAGE_SEUSERS] = strdup(selinux_usersconf_path() + offset); if (semanage_final_suffix[SEMANAGE_SEUSERS] == NULL) { ERR(sh, "Unable to allocate space for userconf path."); status = -1; goto cleanup; } ret = snprintf(path, sizeof(path), "%s.%d", selinux_binary_policy_path() + offset, sh->conf->policyvers); if (ret < 0 || ret >= (int)sizeof(path)) { ERR(sh, "Unable to compose policy binary path."); status = -1; goto cleanup; } semanage_final_suffix[SEMANAGE_KERNEL] = strdup(path); if (semanage_final_suffix[SEMANAGE_KERNEL] == NULL) { ERR(sh, "Unable to allocate space for policy binary path."); status = -1; goto cleanup; } cleanup: if (status != 0) { int i; for (i = 0; i < SEMANAGE_FINAL_PATH_NUM; i++) { free(semanage_final_suffix[i]); semanage_final_suffix[i] = NULL; } } return status; } /* Initialize final paths. */ static int semanage_init_final_paths(semanage_handle_t *sh) { int status = 0; int i, j; for (i = 0; i < SEMANAGE_FINAL_NUM; i++) { for (j = 0; j < SEMANAGE_FINAL_PATH_NUM; j++) { if (asprintf(&semanage_final_paths[i][j], "%s%s", semanage_final[i], semanage_final_suffix[j]) < 0) { semanage_final_paths[i][j] = NULL; ERR(sh, "Unable to allocate space for policy final path."); status = -1; goto cleanup; } } } cleanup: if (status != 0) { for (i = 0; i < SEMANAGE_FINAL_NUM; i++) { for (j = 0; j < SEMANAGE_FINAL_PATH_NUM; j++) { free(semanage_final_paths[i][j]); semanage_final_paths[i][j] = NULL; } } } return status; } /* THIS MUST BE THE FIRST FUNCTION CALLED IN THIS LIBRARY. If the * library has not 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(semanage_handle_t *sh, const char *prefix) { int rc; if (semanage_paths_initialized == 0) { char root[PATH_MAX]; rc = snprintf(root, sizeof(root), "%s%s/%s", semanage_root(), prefix, sh->conf->store_path); if (rc < 0 || rc >= (int)sizeof(root)) return -1; rc = semanage_init_paths(root); if (rc) return rc; rc = semanage_init_store_paths(root); if (rc) return rc; rc = semanage_init_final(sh, prefix); if (rc) return rc; rc = semanage_init_final_suffix(sh); if (rc) return rc; rc = semanage_init_final_paths(sh); 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]; } /* Given a store location (tmp or selinux) 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_final_path(enum semanage_final_defs store, enum semanage_final_path_defs path_name) { assert(semanage_final_paths[store][path_name]); return semanage_final_paths[store][path_name]; } /* Return a fully-qualified path + filename to the semanage * configuration file. If semanage.conf file in the semanage * root is cannot be read, use the default semanage.conf as a * fallback. * * The caller is responsible for freeing the returned string. */ char *semanage_conf_path(void) { char *semanage_conf = NULL; size_t len; struct stat sb; len = strlen(semanage_root()) + strlen(selinux_path()) + strlen(SEMANAGE_CONF_FILE); semanage_conf = calloc(len + 1, sizeof(char)); if (!semanage_conf) return NULL; snprintf(semanage_conf, len + 1, "%s%s%s", semanage_root(), selinux_path(), SEMANAGE_CONF_FILE); if (stat(semanage_conf, &sb) != 0 && errno == ENOENT) { snprintf(semanage_conf, len + 1, "%s%s", selinux_path(), SEMANAGE_CONF_FILE); } return semanage_conf; } /**************** 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; const char *path = semanage_files[SEMANAGE_ROOT]; int fd; mode_t mask; if (stat(path, &sb) == -1) { if (errno == ENOENT && create) { mask = umask(0077); if (mkdir(path, S_IRWXU) == -1) { umask(mask); ERR(sh, "Could not create module store at %s.", path); return -2; } umask(mask); } else { if (create) ERR(sh, "Could not read from module store at %s.", path); return -1; } } else { if (!S_ISDIR(sb.st_mode)) { ERR(sh, "Module store at %s is not a directory.", path); return -1; } } path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL); if (stat(path, &sb) == -1) { if (errno == ENOENT && create) { mask = umask(0077); if (mkdir(path, S_IRWXU) == -1) { umask(mask); ERR(sh, "Could not create module store, active subdirectory at %s.", path); return -2; } umask(mask); } else { ERR(sh, "Could not read from module store, active subdirectory at %s.", path); return -1; } } else { if (!S_ISDIR(sb.st_mode)) { ERR(sh, "Module store active subdirectory at %s is not a directory.", path); return -1; } } path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_MODULES); if (stat(path, &sb) == -1) { if (errno == ENOENT && create) { mask = umask(0077); if (mkdir(path, S_IRWXU) == -1) { umask(mask); ERR(sh, "Could not create module store, active modules subdirectory at %s.", path); return -2; } umask(mask); } else { ERR(sh, "Could not read from module store, active modules subdirectory at %s.", path); return -1; } } else { if (!S_ISDIR(sb.st_mode)) { ERR(sh, "Module store active modules subdirectory at %s is not a directory.", path); return -1; } } path = semanage_files[SEMANAGE_READ_LOCK]; if (stat(path, &sb) == -1) { if (errno == ENOENT && create) { mask = umask(0077); if ((fd = open(path, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IWUSR)) == -1) { umask(mask); ERR(sh, "Could not create lock file at %s.", path); return -2; } umask(mask); close(fd); } else { ERR(sh, "Could not read lock file at %s.", path); return -1; } } else { if (!S_ISREG(sb.st_mode)) { ERR(sh, "Object at %s is not a lock file.", 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 semanage_copy_dir_flags(semanage_handle_t * sh, const char *src, const char *dst, int flag); /* 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; } /* Copies a file from src to dst. If dst already exists then * overwrite it. Returns 0 on success, -1 on error. */ int semanage_copy_file(semanage_handle_t *sh, const char *src, const char *dst, mode_t mode, bool syncrequired) { 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 | O_CLOEXEC)) == -1) { return -1; } if (!mode) mode = S_IRUSR | S_IWUSR; mask = umask(0); if ((out = open(tmp, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode)) == -1) { umask(mask); errsv = errno; close(in); retval = -1; goto out; } umask(mask); while ((amount_read = read(in, buf, sizeof(buf))) > 0) { if (write_full(out, buf, amount_read) == -1) { if (errno) errsv = errno; else errsv = EIO; retval = -1; break; } } if (amount_read < 0) { errsv = errno; retval = -1; } close(in); if (syncrequired && fsync(out) < 0) { errsv = errno; retval = -1; } if (close(out) < 0 && errno != EINTR) { errsv = errno; retval = -1; } if (!retval && rename(tmp, dst) == -1) return -1; semanage_setfiles(sh, dst); out: errno = errsv; return retval; } static int semanage_rename(semanage_handle_t * sh, const char *src, const char *dst) { int retval; retval = rename(src, dst); if (retval == 0 || errno != EXDEV) return retval; /* we can't use rename() due to filesystem limitation, lets try to copy files manually */ WARN(sh, "WARNING: rename(%s, %s) failed: %m, fall back to non-atomic semanage_copy_dir_flags()", src, dst); if (semanage_copy_dir_flags(sh, src, dst, 1) == -1) { return -1; } return semanage_remove_directory(src); } /* Copies all of the files from src to dst, recursing into * subdirectories. Returns 0 on success, -1 on error. */ static int semanage_copy_dir(semanage_handle_t * sh, const char *src, const char *dst) { return semanage_copy_dir_flags(sh, src, dst, 1); } /* Copies all of the dirs from src to dst, recursing into * subdirectories. If flag == 1, then copy regular files as * well. Returns 0 on success, -1 on error. */ static int semanage_copy_dir_flags(semanage_handle_t * sh, const char *src, const char *dst, int flag) { int i, len = 0, rc, retval = -1; struct stat sb; struct dirent **names = NULL; char path[PATH_MAX], path2[PATH_MAX]; mode_t mask; if ((len = scandir(src, &names, semanage_filename_select, NULL)) == -1) { ERR(sh, "Could not read the contents of %s.", src); return -1; } if (stat(dst, &sb) != 0) { mask = umask(0077); if (mkdir(dst, S_IRWXU) != 0) { umask(mask); ERR(sh, "Could not create %s.", dst); goto cleanup; } umask(mask); semanage_setfiles(sh, dst); } for (i = 0; i < len; i++) { rc = snprintf(path, sizeof(path), "%s/%s", src, names[i]->d_name); if (rc < 0 || (size_t)rc >= sizeof(path)) { errno = EOVERFLOW; goto cleanup; } /* 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; } rc = snprintf(path2, sizeof(path2), "%s/%s", dst, names[i]->d_name); if (rc < 0 || (size_t)rc >= sizeof(path2)) { errno = EOVERFLOW; goto cleanup; } if (S_ISDIR(sb.st_mode)) { mask = umask(0077); if (mkdir(path2, 0700) == -1 || semanage_copy_dir_flags(sh, path, path2, flag) == -1) { umask(mask); goto cleanup; } umask(mask); semanage_setfiles(sh, path2); } else if (S_ISREG(sb.st_mode) && flag == 1) { mask = umask(0077); if (semanage_copy_file(sh, path, path2, sb.st_mode, false) < 0) { umask(mask); goto cleanup; } umask(mask); } } 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, rc; if ((num_entries = scandir(path, &namelist, semanage_filename_select, NULL)) == -1) { return -1; } for (i = 0; i < num_entries; i++) { char s[PATH_MAX]; struct stat buf; rc = snprintf(s, sizeof(s), "%s/%s", path, namelist[i]->d_name); if (rc < 0 || (size_t)rc >= sizeof(s)) { errno = EOVERFLOW; return -2; } 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 (unlink(s) == -1) { return -3; } } free(namelist[i]); } free(namelist); if (rmdir(path) == -1) { return -4; } return 0; } int semanage_mkpath(semanage_handle_t *sh, const char *path) { char fn[PATH_MAX]; char *c; int rc = 0; if (strlen(path) >= PATH_MAX) { return -1; } for (c = strcpy(fn, path) + 1; *c != '\0'; c++) { if (*c != '/') { continue; } *c = '\0'; rc = semanage_mkdir(sh, fn); if (rc < 0) { goto cleanup; } *c = '/'; } rc = semanage_mkdir(sh, fn); cleanup: return rc; } int semanage_mkdir(semanage_handle_t *sh, const char *path) { int status = 0; struct stat sb; mode_t mask; /* check if directory already exists */ if (stat(path, &sb) != 0) { /* make the modules directory */ mask = umask(0077); if (mkdir(path, S_IRWXU) != 0) { umask(mask); ERR(sh, "Cannot make directory at %s", path); status = -1; goto cleanup; } umask(mask); semanage_setfiles(sh, path); } else { /* check that it really is a directory */ if (!S_ISDIR(sb.st_mode)) { ERR(sh, "Directory path taken by non-directory file at %s.", path); status = -1; goto cleanup; } } cleanup: return status; } /********************* 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; mode_t mask; 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; } } mask = umask(0077); if (mkdir(sandbox, S_IRWXU) == -1 || semanage_copy_dir(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL), sandbox) == -1) { umask(mask); ERR(sh, "Could not copy files to sandbox %s.", sandbox); goto cleanup; } umask(mask); return 0; cleanup: errsv = errno; semanage_remove_directory(sandbox); errno = errsv; return -1; } /* Create final temporary space. Returns -1 on error 0 on success. */ int semanage_make_final(semanage_handle_t *sh) { int status = 0; int ret = 0; char fn[PATH_MAX]; /* Create tmp dir if it does not exist. */ ret = snprintf(fn, sizeof(fn), "%s%s%s", semanage_root(), sh->conf->store_root_path, semanage_final_prefix[SEMANAGE_FINAL_TMP]); if (ret < 0 || ret >= (int)sizeof(fn)) { ERR(sh, "Unable to compose the final tmp path."); status = -1; goto cleanup; } ret = semanage_mkdir(sh, fn); if (ret != 0) { ERR(sh, "Unable to create temporary directory for final files at %s", fn); status = -1; goto cleanup; } /* Delete store specific dir if it exists. */ ret = semanage_remove_directory( semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FINAL_TOPLEVEL)); if (ret < -1) { status = -1; goto cleanup; } // Build final directory structure int i; for (i = 1; i < SEMANAGE_FINAL_PATH_NUM; i++) { if (strlen(semanage_final_path(SEMANAGE_FINAL_TMP, i)) >= sizeof(fn)) { ERR(sh, "Unable to compose the final paths."); status = -1; goto cleanup; } strcpy(fn, semanage_final_path(SEMANAGE_FINAL_TMP, i)); ret = semanage_mkpath(sh, dirname(fn)); if (ret < 0) { status = -1; goto cleanup; } } cleanup: return status; } /* qsort comparison function for semanage_get_active_modules. */ static int semanage_get_active_modules_cmp(const void *a, const void *b) { const semanage_module_info_t *aa = (const semanage_module_info_t *)a; const semanage_module_info_t *bb = (const semanage_module_info_t *)b; return strcmp(aa->name, bb->name); } int semanage_get_cil_paths(semanage_handle_t * sh, semanage_module_info_t *modinfos, int num_modinfos, char *** filenames) { char path[PATH_MAX]; char **names = NULL; int ret; int status = 0; int i = 0; names = calloc(num_modinfos, sizeof(*names)); if (names == NULL) { ERR(sh, "Error allocating space for filenames."); return -1; } for (i = 0; i < num_modinfos; i++) { ret = semanage_module_get_path( sh, &modinfos[i], SEMANAGE_MODULE_PATH_CIL, path, sizeof(path)); if (ret != 0) { status = -1; goto cleanup; } names[i] = strdup(path); if (names[i] == NULL) { status = -1; goto cleanup; } } cleanup: if (status != 0) { for (i = 0; i < num_modinfos; i++) { free(names[i]); } free(names); } else { *filenames = names; } return status; } /* 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 *modinfos * with an array of module infos; length of array is stored in * *num_modules. The caller is responsible for free()ing *modinfos and its * individual elements. Upon success returns 0, -1 on error. */ int semanage_get_active_modules(semanage_handle_t * sh, semanage_module_info_t ** modinfo, int *num_modules) { assert(sh); assert(modinfo); assert(num_modules); *modinfo = NULL; *num_modules = 0; int status = 0; int ret = 0; int i = 0; int j = 0; semanage_list_t *list = NULL; const semanage_list_t *found = NULL; semanage_module_info_t *all_modinfos = NULL; int all_modinfos_len = 0; void *tmp = NULL; /* get all modules */ ret = semanage_module_list_all(sh, &all_modinfos, &all_modinfos_len); if (ret != 0) { status = -1; goto cleanup; } if (all_modinfos_len == 0) { goto cleanup; } /* allocate enough for worst case */ (*modinfo) = calloc(all_modinfos_len, sizeof(**modinfo)); if ((*modinfo) == NULL) { ERR(sh, "Error allocating space for module information."); status = -1; goto cleanup; } /* for each highest priority, enabled module get its path */ semanage_list_destroy(&list); j = 0; for (i = 0; i < all_modinfos_len; i++) { /* check if enabled */ if (all_modinfos[i].enabled != 1) continue; /* check if we've seen this before (i.e. highest priority) */ found = semanage_list_find(list, all_modinfos[i].name); if (found == NULL) { ret = semanage_list_push(&list, all_modinfos[i].name); if (ret != 0) { ERR(sh, "Failed to add module name to list of known names."); status = -1; goto cleanup; } } else continue; if (semanage_module_info_clone(sh, &all_modinfos[i], &(*modinfo)[j]) != 0) { status = -1; goto cleanup; } j += 1; } *num_modules = j; if (j == 0) { free(*modinfo); *modinfo = NULL; goto cleanup; } /* realloc the array to its min size */ tmp = realloc(*modinfo, j * sizeof(**modinfo)); if (tmp == NULL) { ERR(sh, "Error allocating space for filenames."); status = -1; goto cleanup; } *modinfo = tmp; /* sort array on module name */ qsort(*modinfo, *num_modules, sizeof(**modinfo), semanage_get_active_modules_cmp); cleanup: semanage_list_destroy(&list); for (i = 0; i < all_modinfos_len; i++) { semanage_module_info_destroy(sh, &all_modinfos[i]); } free(all_modinfos); if (status != 0) { for (i = 0; i < j; i++) { semanage_module_info_destroy(sh, &(*modinfo)[i]); } free(*modinfo); } return status; } /******************* 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; char *new_s; if (t == NULL) { return s; } t_len = strlen(t); 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, * respecting 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((unsigned char)*s) && !in_quote && !in_dquote) { if (arg != NULL) { rc = append_arg(&argv, &num_args, arg); if (rc) goto cleanup; 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); if (rc) goto cleanup; 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; } /* 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), "re"); 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_STORE_FC), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IWUSR); if (fc < 0) { ERR(sh, "Could not open %s for writing.", semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC)); goto cleanup; } hd = open(semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 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_full(hd, buf, strlen(buf)) < 0) { ERR(sh, "Write to %s failed.", semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL)); goto cleanup; } } else { if (write_full(fc, buf, strlen(buf)) < 0) { ERR(sh, "Write to %s failed.", semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC)); goto cleanup; } } } retval = 0; cleanup: if (file_con) fclose(file_con); if (fc >= 0) if (close(fc) == -1 && errno != EINTR) retval = -1; if (hd >= 0) if (close(hd) == -1 && errno != EINTR) retval = -1; return retval; } static int sefcontext_compile(semanage_handle_t * sh, const char *path) { int r; struct stat sb; if (stat(path, &sb) < 0) { if (errno != ENOENT) { ERR(sh, "Unable to access %s.", path); return -1; } return 0; } 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; } static int semanage_validate_and_compile_fcontexts(semanage_handle_t * sh) { int status = -1; if (sh->do_check_contexts) { int ret; ret = semanage_exec_prog( sh, sh->conf->setfiles, semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL), semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC)); if (ret != 0) { ERR(sh, "setfiles returned error code %d.", ret); goto cleanup; } } if (sefcontext_compile(sh, semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC)) != 0) { goto cleanup; } semanage_setfiles(sh, semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_BIN)); if (sefcontext_compile(sh, semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL)) != 0) { goto cleanup; } semanage_setfiles(sh, semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL_BIN)); if (sefcontext_compile(sh, semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS)) != 0) { goto cleanup; } semanage_setfiles(sh, semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS_BIN)); status = 0; cleanup: return status; } /* Load the contexts of the final tmp into the final selinux directory. * Return 0 on success, -3 on error. */ static int semanage_install_final_tmp(semanage_handle_t * sh) { int status = -3; int ret = 0; int i = 0; const char *src = NULL; const char *dst = NULL; struct stat sb; char fn[PATH_MAX]; /* For each of the final files install it if it exists. * i = 1 to avoid copying the top level directory. */ for (i = 1; i < SEMANAGE_FINAL_PATH_NUM; i++) { src = semanage_final_path(SEMANAGE_FINAL_TMP, i); dst = semanage_final_path(SEMANAGE_FINAL_SELINUX, i); /* skip file if src doesn't exist */ if (stat(src, &sb) != 0) continue; /* skip genhomedircon if configured */ if (sh->conf->disable_genhomedircon && i == SEMANAGE_FC_HOMEDIRS) continue; if (strlen(dst) >= sizeof(fn)) { ERR(sh, "Unable to compose the final paths."); status = -1; goto cleanup; } strcpy(fn, dst); ret = semanage_mkpath(sh, dirname(fn)); if (ret < 0) { goto cleanup; } ret = semanage_copy_file(sh, src, dst, sh->conf->file_mode, true); if (ret < 0) { ERR(sh, "Could not copy %s to %s.", src, dst); goto cleanup; } } 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. */ const char *really_active_store = selinux_policy_root(); struct stat astore; struct stat istore; const char *storepath = semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FINAL_TOPLEVEL); 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: status = 0; cleanup: return status; } /* 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; struct selabel_handle *sehandle; /* 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 | O_CLOEXEC, S_IRUSR | S_IWUSR)) == -1) { ERR(sh, "Could not open commit number file %s for writing.", commit_filename); return -1; } amount_written = write_full(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; } if (close(fd) == -1 && errno != EINTR) { ERR(sh, "Error while closing commit number file %s.", commit_filename); return -1; } /* sync changes in sandbox to filesystem */ fd = open(sandbox, O_DIRECTORY | O_CLOEXEC); if (fd == -1) { ERR(sh, "Error while opening %s for syncfs().", sandbox); return -1; } if (syncfs(fd) == -1) { ERR(sh, "Error while syncing %s to filesystem.", sandbox); 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 (semanage_rename(sh, 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 (semanage_rename(sh, 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 (semanage_rename(sh, backup, active) < 0) ERR(sh, "Error while renaming %s back to %s.", backup, active); retval = -1; goto cleanup; } if (semanage_install_final_tmp(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 (semanage_rename(sh, active, sandbox) < 0) ERR(sh, "Error while renaming %s back to %s.", active, sandbox); else if (semanage_rename(sh, backup, active) < 0) ERR(sh, "Error while renaming %s back to %s.", backup, active); else semanage_install_final_tmp(sh); errno = errsv; retval = -1; goto cleanup; } if (!sh->conf->save_previous) { int errsv = errno; if (semanage_remove_directory(backup) != 0) { ERR(sh, "Could not delete previous directory %s.", backup); retval = -1; goto cleanup; } errno = errsv; } cleanup: semanage_release_active_lock(sh); sehandle = selinux_restorecon_default_handle(); selinux_restorecon_set_sehandle(sehandle); 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 (semanage_validate_and_compile_fcontexts(sh) < 0) 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_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 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 | O_CLOEXEC)) == -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 */ int semanage_load_files(semanage_handle_t * sh, cil_db_t *cildb, char **filenames, int numfiles) { int i, retval; const char *filename; struct file_contents contents = {}; for (i = 0; i < numfiles; i++) { filename = filenames[i]; retval = map_compressed_file(sh, filename, &contents); if (retval < 0) return -1; retval = cil_add_file(cildb, filename, contents.data, contents.len); unmap_compressed_file(&contents); if (retval != SEPOL_OK) { ERR(sh, "Error while reading from file %s.", filename); return -1; } } return 0; } /* * Expands the policy contained within *base */ /** * Read the policy from the sandbox (linked or kernel) */ int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in, enum semanage_sandbox_defs file) { 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, file)) == NULL) { goto cleanup; } if ((infile = fopen(kernel_filename, "re")) == 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 policy to the sandbox (linked or kernel) */ int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out, enum semanage_sandbox_defs file) { int retval = STATUS_ERR; const char *kernel_filename = NULL; struct sepol_policy_file *pf = NULL; FILE *outfile = NULL; mode_t mask = umask(0077); if ((kernel_filename = semanage_path(SEMANAGE_TMP, file)) == NULL) { goto cleanup; } if ((outfile = fopen(kernel_filename, "wbe")) == 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) { if (fclose(outfile) != 0 && errno != EINTR) { retval = STATUS_ERR; } } umask(mask); 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; semanage_conf_t *conf = sh->conf; if (conf->mod_prog == NULL) { return 0; } for (i = 0; i < num_modules; i++) { const char *module = module_filenames[i]; external_prog_t *e; for (e = conf->mod_prog; e != NULL; e = e->next) { if (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_final_path(SEMANAGE_FINAL_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(const semanage_file_context_node_t * a, const 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 "main") 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 * main) { semanage_file_context_bucket_t *current; semanage_file_context_bucket_t *temp; /* Loop until "main" is the only bucket left. * When we stop "main" contains the sorted list. */ while (main->next) { current = main; /* 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 *main; semanage_file_context_bucket_t *bcurrent; 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((unsigned char)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((unsigned char)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 = 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((unsigned char)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 = 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((unsigned char)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((unsigned char)line_buf[i]))) i++; finish = i; context_len = finish - start; temp->context = 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 = main = (semanage_file_context_bucket_t *) calloc(1, sizeof(semanage_file_context_bucket_t)); if (!main) { 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(main); return -1; } bcurrent = bcurrent->next; } } /* Sort the bucket list. */ semanage_fc_merge_sort(main); /* 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 = main->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(main); return -1; } *sorted_buf_len = i; /* Output the sorted semanage_file_context linked list to the char buffer. */ sorted_buf_pos = *sorted_buf; current = main->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(main); /* 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 size_t 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((unsigned char)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((unsigned char)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 = 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; } /* log_callback muting all logs */ static int __attribute__ ((format(printf, 2, 3))) log_callback_mute(__attribute__((unused)) int type, __attribute__((unused)) const char *fmt, ...) { return 0; } /* Make sure the file context and ownership of files in the policy * store does not change */ void semanage_setfiles(semanage_handle_t * sh, const char *path){ struct stat sb; int fd; union selinux_callback cb_orig = selinux_get_callback(SELINUX_CB_LOG); union selinux_callback cb = { .func_log = log_callback_mute }; /* Mute all logs */ selinux_set_callback(SELINUX_CB_LOG, cb); /* Fix the user and role portions of the context, ignore errors * since this is not a critical operation */ selinux_restorecon(path, SELINUX_RESTORECON_SET_SPECFILE_CTX | SELINUX_RESTORECON_IGNORE_NOENTRY); /* restore log_logging */ selinux_set_callback(SELINUX_CB_LOG, cb_orig); /* Make sure "path" is owned by root */ if ((geteuid() != 0 || getegid() != 0) && ((fd = open(path, O_RDONLY | O_CLOEXEC)) != -1)){ /* Skip files with the SUID or SGID bit set -- abuse protection */ if ((fstat(fd, &sb) != -1) && !(S_ISREG(sb.st_mode) && (sb.st_mode & (S_ISUID | S_ISGID))) && (fchown(fd, 0, 0) == -1)) ERR(sh, "Warning! Could not set ownership of %s to root", path); close(fd); } } libsemanage-3.8.1/src/semanage_store.h000066400000000000000000000120201476211737200177330ustar00rootroot00000000000000/* 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 #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_LINKED, SEMANAGE_HOMEDIR_TMPL, SEMANAGE_FC_TMPL, SEMANAGE_COMMIT_NUM_FILE, SEMANAGE_IBPKEYS_LOCAL, SEMANAGE_IBENDPORTS_LOCAL, SEMANAGE_PORTS_LOCAL, SEMANAGE_INTERFACES_LOCAL, SEMANAGE_NODES_LOCAL, SEMANAGE_BOOLEANS_LOCAL, SEMANAGE_SEUSERS_LOCAL, SEMANAGE_SEUSERS_LINKED, SEMANAGE_USERS_BASE_LOCAL, SEMANAGE_USERS_EXTRA_LOCAL, SEMANAGE_USERS_EXTRA_LINKED, SEMANAGE_USERS_EXTRA, SEMANAGE_DISABLE_DONTAUDIT, SEMANAGE_PRESERVE_TUNABLES, SEMANAGE_MODULES_DISABLED, SEMANAGE_MODULES_CHECKSUM, SEMANAGE_STORE_KERNEL, SEMANAGE_STORE_FC_LOCAL, SEMANAGE_STORE_FC_HOMEDIRS, SEMANAGE_STORE_FC, SEMANAGE_STORE_SEUSERS, SEMANAGE_STORE_NUM_PATHS }; enum semanage_final_defs { SEMANAGE_FINAL_TMP, SEMANAGE_FINAL_SELINUX, SEMANAGE_FINAL_NUM }; enum semanage_final_path_defs { SEMANAGE_FINAL_TOPLEVEL, SEMANAGE_FC, SEMANAGE_FC_BIN, SEMANAGE_FC_HOMEDIRS, SEMANAGE_FC_HOMEDIRS_BIN, SEMANAGE_FC_LOCAL, SEMANAGE_FC_LOCAL_BIN, SEMANAGE_KERNEL, SEMANAGE_NC, SEMANAGE_SEUSERS, SEMANAGE_FINAL_PATH_NUM }; /* FIXME: this needs to be made a module store specific init and the * global configuration moved to another file. */ char *semanage_conf_path(void); int semanage_check_init(semanage_handle_t *sh, const char *prefix); 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); extern const char *semanage_final_path(enum semanage_final_defs root, enum semanage_final_path_defs suffix); 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_mkdir(semanage_handle_t *sh, const char *path); int semanage_mkpath(semanage_handle_t *sh, const char *path); int semanage_make_sandbox(semanage_handle_t * sh); int semanage_make_final(semanage_handle_t * sh); int semanage_get_cil_paths(semanage_handle_t * sh, semanage_module_info_t *modinfos, int len, char ***filenames); int semanage_get_active_modules(semanage_handle_t *sh, semanage_module_info_t **modinfo, int *num_modules); void semanage_setfiles(semanage_handle_t * sh, const char *path); /* 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_load_files(semanage_handle_t * sh, cil_db_t *cildb, char **filenames, int num_modules); int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * policydb, enum semanage_sandbox_defs file); int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * policydb, enum semanage_sandbox_defs file); 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); int semanage_copy_file(semanage_handle_t * sh, const char *src, const char *dst, mode_t mode, bool syncrequired); #endif libsemanage-3.8.1/src/semanageswig.i000066400000000000000000000046571476211737200174330ustar00rootroot00000000000000/* 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/ibpkey_record.h" %include "../include/semanage/ibpkeys_local.h" %include "../include/semanage/ibpkeys_policy.h" %include "../include/semanage/ibendport_record.h" %include "../include/semanage/ibendports_local.h" %include "../include/semanage/ibendports_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-3.8.1/src/semanageswig_python.i000066400000000000000000000362561476211737200210340ustar00rootroot00000000000000/* 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 #include #define STATUS_SUCCESS 0 #define STATUS_ERR -1 %} %include "stdint.i" %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 * }; %apply int *OUTPUT { uint16_t * }; %include /* This is needed to properly mmap binary data in SWIG */ %cstring_output_allocate_size(void **mapped_data, size_t *data_len, munmap(*$1, *$2)); %typemap(in, numinputs=0) char **(char *temp=NULL) { $1 = &temp; } %typemap(argout) char** { $result = SWIG_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_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_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } /** module key typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_module_key_t ** parameter */ %typemap(in, numinputs=0) semanage_module_key_t **(semanage_module_key_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_module_key_t ** { $result = SWIG_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_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_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_bool_t **(semanage_bool_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_bool_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_bool_key_t ** { $result = SWIG_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_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_fcontext_t **(semanage_fcontext_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_fcontext_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_fcontext_key_t ** { $result = SWIG_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_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_iface_t **(semanage_iface_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_iface_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_iface_key_t ** { $result = SWIG_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_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_seuser_t **(semanage_seuser_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_seuser_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_seuser_key_t ** { $result = SWIG_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_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_user_t **(semanage_user_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_user_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_user_key_t ** { $result = SWIG_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_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_port_t **(semanage_port_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_port_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_port_key_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_port_key_t **(semanage_port_key_t *temp=NULL) { $1 = &temp; } /** ibpkey typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_ibpkey_t *** parameter */ %typemap(in, numinputs=0) semanage_ibpkey_t ***(semanage_ibpkey_t **temp=NULL) { $1 = &temp; } %typemap(argout) ( semanage_handle_t* handle, semanage_ibpkey_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_ibpkey, (void (*) (void*)) &semanage_ibpkey_free, &plist) < 0) $result = SWIG_From_int(STATUS_ERR); else $result = SWIG_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_ibpkey_t **(semanage_ibpkey_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_ibpkey_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_ibpkey_key_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_ibpkey_key_t **(semanage_ibpkey_key_t *temp=NULL) { $1 = &temp; } /** ibendport typemaps **/ /* the wrapper will setup this parameter for passing... the resulting python functions will not take the semanage_ibendport_t *** parameter */ %typemap(in, numinputs=0) semanage_ibendport_t ***(semanage_ibendport_t **temp=NULL) { $1 = &temp; } %typemap(argout) ( semanage_handle_t* handle, semanage_ibendport_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_ibendport, (void (*) (void*)) &semanage_ibendport_free, &plist) < 0) $result = SWIG_From_int(STATUS_ERR); else $result = SWIG_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_ibendport_t **(semanage_ibendport_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_ibendport_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_ibendport_key_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(in, numinputs=0) semanage_ibendport_key_t **(semanage_ibendport_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_AppendOutput($result, plist); } } } %typemap(in, numinputs=0) semanage_node_t **(semanage_node_t *temp=NULL) { $1 = &temp; } %typemap(argout) semanage_node_t ** { $result = SWIG_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_node_key_t ** { $result = SWIG_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-3.8.1/src/semanageswig_python_exception.i000066400000000000000000001042471476211737200231060ustar00rootroot00000000000000 %exception semanage_reload_policy { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_get_hll_compiler_path { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_get_disable_dontaudit { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_set_default_priority { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_is_managed { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_connect { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_disconnect { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_begin_transaction { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_commit { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_access_check { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_is_connected { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_mls_enabled { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_set_root { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_get_preserve_tunables { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_get_ignore_module_cache { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception select { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception pselect { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_install { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_install_file { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_remove { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_extract { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_list { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_info_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_info_destroy { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_info_get_priority { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_info_get_name { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_info_get_lang_ext { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_info_get_enabled { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_info_set_priority { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_info_set_name { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_info_set_lang_ext { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_info_set_enabled { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_key_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_key_destroy { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_key_get_name { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_key_get_priority { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_key_set_name { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_key_set_priority { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_set_enabled { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_get_module_info { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_list_all { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_install_info { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_remove_key { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_get_enabled { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_module_compute_checksum { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_msg_get_level { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_key_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_key_extract { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_compare { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_compare2 { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_set_name { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_get_value { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_clone { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_key_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_key_extract { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_compare { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_compare2 { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_set_name { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_set_prefix { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_set_mlslevel { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_set_mlsrange { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_get_num_roles { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_add_role { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_has_role { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_get_roles { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_set_roles { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_clone { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_key_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_key_extract { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_compare { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_compare2 { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_set_name { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_set_sename { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_set_mlsrange { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_clone { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_context_set_user { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_context_set_role { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_context_set_type { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_context_set_mls { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_context_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_context_clone { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_context_from_string { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_context_to_string { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_compare { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_compare2 { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_key_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_key_extract { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_set_name { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_set_ifcon { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_set_msgcon { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_clone { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_compare { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_compare2 { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_key_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_key_extract { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_get_proto { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_get_low { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_get_high { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_set_con { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_clone { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_compare { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_compare2 { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_key_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_key_extract { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_get_subnet_prefix { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_set_subnet_prefix { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_get_low { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_get_high { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_set_con { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_clone { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_compare { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_compare2 { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_key_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_key_extract { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_get_ibdev_name { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_set_ibdev_name { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_get_port { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_set_con { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_clone { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_compare { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_compare2 { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_key_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_key_extract { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_get_addr { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_get_addr_bytes { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_set_addr { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_set_addr_bytes { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_get_mask { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_get_mask_bytes { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_set_mask { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_set_mask_bytes { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_get_proto { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_set_con { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_clone { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_modify_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_del_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_query_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_exists_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_count_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_iterate_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_list_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_query { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_exists { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_count { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_iterate { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_list { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_set_active { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_query_active { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_exists_active { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_count_active { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_iterate_active { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_bool_list_active { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_modify_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_del_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_query_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_exists_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_count_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_iterate_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_list_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_query { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_exists { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_count { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_iterate { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_user_list { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_compare { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_compare2 { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_key_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_key_extract { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_set_expr { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_get_type { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_set_con { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_create { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_clone { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_modify_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_del_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_query_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_exists_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_count_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_iterate_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_list_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_query { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_exists { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_count { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_iterate { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_list { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_fcontext_list_homedirs { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_modify_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_del_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_query_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_exists_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_count_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_iterate_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_list_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_query { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_exists { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_count { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_iterate { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_seuser_list { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_modify_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_del_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_query_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_exists_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_count_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_iterate_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_list_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_query { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_exists { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_count { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_iterate { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_port_list { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_modify_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_del_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_query_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_exists_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_count_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_iterate_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_list_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_modify_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_del_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_query_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_exists_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_count_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_iterate_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_list_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_query { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_exists { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_count { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_iterate { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibendport_list { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_query { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_exists { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_count { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_iterate { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_ibpkey_list { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_modify_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_del_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_query_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_exists_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_count_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_iterate_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_list_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_query { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_exists { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_count { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_iterate { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_iface_list { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_modify_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_del_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_query_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_exists_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_count_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_iterate_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_list_local { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_query { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_exists { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_count { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_iterate { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } %exception semanage_node_list { $action if (result < 0) { PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } } libsemanage-3.8.1/src/semanageswig_ruby.i000066400000000000000000000152571476211737200204720ustar00rootroot00000000000000/* 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_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_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_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_bool_key_t ** { $result = SWIG_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_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_fcontext_key_t ** { $result = SWIG_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_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_iface_key_t ** { $result = SWIG_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_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_seuser_key_t ** { $result = SWIG_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_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_user_key_t ** { $result = SWIG_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_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_port_key_t ** { $result = SWIG_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_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); } %typemap(argout) semanage_node_key_t ** { $result = SWIG_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-3.8.1/src/seuser_internal.h000066400000000000000000000012561476211737200201520ustar00rootroot00000000000000#ifndef _SEMANAGE_SEUSER_INTERNAL_H_ #define _SEMANAGE_SEUSER_INTERNAL_H_ #include #include #include #include #include "database.h" #include "handle.h" /* SEUSER RECORD: method table */ extern const record_table_t SEMANAGE_SEUSER_RTABLE; extern int seuser_file_dbase_init(semanage_handle_t * handle, const char *path_ro, const char *path_rw, dbase_config_t * dconfig); extern void seuser_file_dbase_release(dbase_config_t * dconfig); extern int semanage_seuser_validate_local(semanage_handle_t * handle, const sepol_policydb_t * policydb); #endif libsemanage-3.8.1/src/seuser_record.c000066400000000000000000000125331476211737200176070ustar00rootroot00000000000000/* 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 */ 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 = strdup(name); if (!tmp_key->name) { ERR(handle, "out of memory, could not create seuser key"); free(tmp_key); return STATUS_ERR; } *key_ptr = tmp_key; return STATUS_SUCCESS; } 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; } void semanage_seuser_key_free(semanage_seuser_key_t * key) { free(key->name); free(key); } int semanage_seuser_compare(const semanage_seuser_t * seuser, const semanage_seuser_key_t * key) { return strcmp(seuser->name, key->name); } int semanage_seuser_compare2(const semanage_seuser_t * seuser, const semanage_seuser_t * seuser2) { return strcmp(seuser->name, seuser2->name); } static int semanage_seuser_compare2_qsort(const void *p1, const void *p2) { const semanage_seuser_t *const *seuser1 = p1; const semanage_seuser_t *const *seuser2 = p2; return semanage_seuser_compare2(*seuser1, *seuser2); } /* Name */ const char *semanage_seuser_get_name(const semanage_seuser_t * seuser) { return seuser->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; } /* Selinux Name */ const char *semanage_seuser_get_sename(const semanage_seuser_t * seuser) { return seuser->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; } /* MLS Range */ const char *semanage_seuser_get_mlsrange(const semanage_seuser_t * seuser) { return seuser->mls_range; } 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; } /* 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; } /* 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; } /* Destroy */ void semanage_seuser_free(semanage_seuser_t * seuser) { if (!seuser) return; free(seuser->name); free(seuser->sename); free(seuser->mls_range); free(seuser); } /* Record base functions */ const 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-3.8.1/src/seusers_file.c000066400000000000000000000057421476211737200174370ustar00rootroot00000000000000/* 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, const 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, ':', 1) < 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, ':', 1) < 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) < 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 */ static const 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 *path_ro, const char *path_rw, dbase_config_t * dconfig) { if (dbase_file_init(handle, path_ro, path_rw, &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-3.8.1/src/seusers_local.c000066400000000000000000000214471476211737200176120ustar00rootroot00000000000000/* 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; } rc = semanage_seuser_clone(handle, data, &new); if (rc < 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); } 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 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-3.8.1/src/seusers_policy.c000066400000000000000000000030701476211737200200070ustar00rootroot00000000000000/* 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); } 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-3.8.1/src/sha256.c000066400000000000000000000247241476211737200157600ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // WjCryptLib_Sha256 // // Implementation of SHA256 hash function. // Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org // Modified by WaterJuice retaining Public Domain license. // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include "sha256.h" #include //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MACROS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define ror(value, bits) (((value) >> (bits)) | ((value) << (32 - (bits)))) #define MIN(x, y) ( ((x)<(y))?(x):(y) ) #define STORE32H(x, y) \ { (y)[0] = (uint8_t)(((x)>>24)&255); (y)[1] = (uint8_t)(((x)>>16)&255); \ (y)[2] = (uint8_t)(((x)>>8)&255); (y)[3] = (uint8_t)((x)&255); } #define LOAD32H(x, y) \ { x = ((uint32_t)((y)[0] & 255)<<24) | \ ((uint32_t)((y)[1] & 255)<<16) | \ ((uint32_t)((y)[2] & 255)<<8) | \ ((uint32_t)((y)[3] & 255)); } #define STORE64H(x, y) \ { (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255); \ (y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255); \ (y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255); \ (y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CONSTANTS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // The K array static const uint32_t K[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; #define BLOCK_SIZE 64 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // INTERNAL FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Various logical functions #define Ch( x, y, z ) (z ^ (x & (y ^ z))) #define Maj( x, y, z ) (((x | y) & z) | (x & y)) #define S( x, n ) ror((x),(n)) #define R( x, n ) (((x)&0xFFFFFFFFUL)>>(n)) #define Sigma0( x ) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) #define Sigma1( x ) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) #define Gamma0( x ) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) #define Gamma1( x ) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) #define Sha256Round( a, b, c, d, e, f, g, h, i ) \ t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ t1 = Sigma0(a) + Maj(a, b, c); \ d += t0; \ h = t0 + t1; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TransformFunction // // Compress 512-bits //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static void TransformFunction ( Sha256Context* Context, uint8_t const* Buffer ) { uint32_t S[8]; uint32_t W[64]; uint32_t t0; uint32_t t1; uint32_t t; int i; // Copy state into S for( i=0; i<8; i++ ) { S[i] = Context->state[i]; } // Copy the state into 512-bits into W[0..15] for( i=0; i<16; i++ ) { LOAD32H( W[i], Buffer + (4*i) ); } // Fill W[16..63] for( i=16; i<64; i++ ) { W[i] = Gamma1( W[i-2]) + W[i-7] + Gamma0( W[i-15] ) + W[i-16]; } // Compress for( i=0; i<64; i++ ) { Sha256Round( S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i ); t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; } // Feedback for( i=0; i<8; i++ ) { Context->state[i] = Context->state[i] + S[i]; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Initialise // // Initialises a SHA256 Context. Use this to initialise/reset a context. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Initialise ( Sha256Context* Context // [out] ) { Context->curlen = 0; Context->length = 0; Context->state[0] = 0x6A09E667UL; Context->state[1] = 0xBB67AE85UL; Context->state[2] = 0x3C6EF372UL; Context->state[3] = 0xA54FF53AUL; Context->state[4] = 0x510E527FUL; Context->state[5] = 0x9B05688CUL; Context->state[6] = 0x1F83D9ABUL; Context->state[7] = 0x5BE0CD19UL; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Update // // Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on // calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Update ( Sha256Context* Context, // [in out] void const* Buffer, // [in] size_t BufferSize // [in] ) { uint32_t n; if( Context->curlen > sizeof(Context->buf) ) { return; } while( BufferSize > 0 ) { if( Context->curlen == 0 && BufferSize >= BLOCK_SIZE ) { TransformFunction( Context, (const uint8_t*)Buffer ); Context->length += BLOCK_SIZE * 8; Buffer = (const uint8_t*)Buffer + BLOCK_SIZE; BufferSize -= BLOCK_SIZE; } else { n = MIN( BufferSize, (BLOCK_SIZE - Context->curlen) ); memcpy( Context->buf + Context->curlen, Buffer, (size_t)n ); Context->curlen += n; Buffer = (const uint8_t*)Buffer + n; BufferSize -= n; if( Context->curlen == BLOCK_SIZE ) { TransformFunction( Context, Context->buf ); Context->length += 8*BLOCK_SIZE; Context->curlen = 0; } } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Finalise // // Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After // calling this, Sha256Initialised must be used to reuse the context. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Finalise ( Sha256Context* Context, // [in out] SHA256_HASH* Digest // [out] ) { int i; if( Context->curlen >= sizeof(Context->buf) ) { return; } // Increase the length of the message Context->length += Context->curlen * 8; // Append the '1' bit Context->buf[Context->curlen++] = (uint8_t)0x80; // if the length is currently above 56 bytes we append zeros // then compress. Then we can fall back to padding zeros and length // encoding like normal. if( Context->curlen > 56 ) { while( Context->curlen < 64 ) { Context->buf[Context->curlen++] = (uint8_t)0; } TransformFunction(Context, Context->buf); Context->curlen = 0; } // Pad up to 56 bytes of zeroes while( Context->curlen < 56 ) { Context->buf[Context->curlen++] = (uint8_t)0; } // Store length STORE64H( Context->length, Context->buf+56 ); TransformFunction( Context, Context->buf ); // Copy output for( i=0; i<8; i++ ) { STORE32H( Context->state[i], Digest->bytes+(4*i) ); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Calculate // // Combines Sha256Initialise, Sha256Update, and Sha256Finalise into one function. Calculates the SHA256 hash of the // buffer. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Calculate ( void const* Buffer, // [in] size_t BufferSize, // [in] SHA256_HASH* Digest // [in] ) { Sha256Context context; Sha256Initialise( &context ); Sha256Update( &context, Buffer, BufferSize ); Sha256Finalise( &context, Digest ); } libsemanage-3.8.1/src/sha256.h000066400000000000000000000071501476211737200157570ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // WjCryptLib_Sha256 // // Implementation of SHA256 hash function. // Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org // Modified by WaterJuice retaining Public Domain license. // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma once //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #include typedef struct { uint64_t length; uint32_t state[8]; uint32_t curlen; uint8_t buf[64]; } Sha256Context; #define SHA256_HASH_SIZE ( 256 / 8 ) typedef struct { uint8_t bytes [SHA256_HASH_SIZE]; } SHA256_HASH; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Initialise // // Initialises a SHA256 Context. Use this to initialise/reset a context. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Initialise ( Sha256Context* Context // [out] ); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Update // // Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on // calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Update ( Sha256Context* Context, // [in out] void const* Buffer, // [in] size_t BufferSize // [in] ); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Finalise // // Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After // calling this, Sha256Initialised must be used to reuse the context. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Finalise ( Sha256Context* Context, // [in out] SHA256_HASH* Digest // [out] ); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Calculate // // Combines Sha256Initialise, Sha256Update, and Sha256Finalise into one function. Calculates the SHA256 hash of the // buffer. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Calculate ( void const* Buffer, // [in] size_t BufferSize, // [in] SHA256_HASH* Digest // [in] ); libsemanage-3.8.1/src/user_base_record.c000066400000000000000000000105321476211737200202460ustar00rootroot00000000000000/* 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 */ 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 void *p1, const void *p2) { const semanage_user_base_t *const *user1 = p1; const semanage_user_base_t *const *user2 = p2; return sepol_user_compare2(*user1, *user2); } /* Name */ const char *semanage_user_base_get_name(const semanage_user_base_t * user) { return sepol_user_get_name(user); } 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 */ const char *semanage_user_base_get_mlslevel(const semanage_user_base_t * user) { return sepol_user_get_mlslevel(user); } 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); } const char *semanage_user_base_get_mlsrange(const semanage_user_base_t * user) { return sepol_user_get_mlsrange(user); } 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 */ int semanage_user_base_get_num_roles(const semanage_user_base_t * user) { return sepol_user_get_num_roles(user); } 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); } void semanage_user_base_del_role(semanage_user_base_t * user, const char *role) { sepol_user_del_role(user, role); } int semanage_user_base_has_role(const semanage_user_base_t * user, const char *role) { return sepol_user_has_role(user, role); } 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); } 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 */ int semanage_user_base_create(semanage_handle_t * handle, semanage_user_base_t ** user_ptr) { return sepol_user_create(handle->sepolh, user_ptr); } 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); } void semanage_user_base_free(semanage_user_base_t * user) { sepol_user_free(user); } /* Record base functions */ const 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-3.8.1/src/user_extra_record.c000066400000000000000000000111431476211737200204560ustar00rootroot00000000000000/* 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 void *p1, const void *p2) { const semanage_user_extra_t *const *user_extra1 = p1; const semanage_user_extra_t *const *user_extra2 = p2; return semanage_user_extra_compare2(*user_extra1, *user_extra2); } /* Name */ const char *semanage_user_extra_get_name(const semanage_user_extra_t * user_extra) { return user_extra->name; } 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 */ const char *semanage_user_extra_get_prefix(const semanage_user_extra_t * user_extra) { return user_extra->prefix; } 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 */ 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 */ 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 */ 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 */ const 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-3.8.1/src/user_internal.h000066400000000000000000000117601476211737200176230ustar00rootroot00000000000000#ifndef _SEMANAGE_USER_INTERNAL_H_ #define _SEMANAGE_USER_INTERNAL_H_ #include #include #include #include #include "database.h" #include "handle.h" /* USER record: method table */ extern const record_table_t SEMANAGE_USER_RTABLE; /* USER BASE record: method table */ extern const record_table_t SEMANAGE_USER_BASE_RTABLE; /* USER EXTRA record: method table */ extern const 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 *path_ro, const char *path_rw, 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 *path_ro, const char *path_rw, 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 int semanage_user_base_create(semanage_handle_t * handle, semanage_user_base_t ** user_ptr); int semanage_user_base_clone(semanage_handle_t * handle, const semanage_user_base_t * user, semanage_user_base_t ** user_ptr); int semanage_user_base_key_extract(semanage_handle_t * handle, const semanage_user_base_t * user, semanage_user_key_t ** key); const char *semanage_user_base_get_name(const semanage_user_base_t * user); int semanage_user_base_set_name(semanage_handle_t * handle, semanage_user_base_t * user, const char *name); const char *semanage_user_base_get_mlslevel(const semanage_user_base_t * user); int semanage_user_base_set_mlslevel(semanage_handle_t * handle, semanage_user_base_t * user, const char *mls_level); const char *semanage_user_base_get_mlsrange(const semanage_user_base_t * user); int semanage_user_base_set_mlsrange(semanage_handle_t * handle, semanage_user_base_t * user, const char *mls_range); int semanage_user_base_get_num_roles(const semanage_user_base_t * user); int semanage_user_base_add_role(semanage_handle_t * handle, semanage_user_base_t * user, const char *role); void semanage_user_base_del_role(semanage_user_base_t * user, const char *role); int semanage_user_base_has_role(const semanage_user_base_t * user, const char *role); int semanage_user_base_get_roles(semanage_handle_t * handle, const semanage_user_base_t * user, const char ***roles_arr, unsigned int *num_roles); int semanage_user_base_set_roles(semanage_handle_t * handle, semanage_user_base_t * user, const char **roles_arr, unsigned int num_roles); 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; int semanage_user_extra_create(semanage_handle_t * handle, semanage_user_extra_t ** user_extra_ptr); int semanage_user_extra_clone(semanage_handle_t * handle, const semanage_user_extra_t * user_extra, semanage_user_extra_t ** user_extra_ptr); const char *semanage_user_extra_get_name(const semanage_user_extra_t * user_extra); int semanage_user_extra_set_name(semanage_handle_t * handle, semanage_user_extra_t * user_extra, const char *name); const char *semanage_user_extra_get_prefix(const semanage_user_extra_t * user_extra); int semanage_user_extra_set_prefix(semanage_handle_t * handle, semanage_user_extra_t * user_extra, const char *prefix); void semanage_user_extra_free(semanage_user_extra_t * user_extra); /*======== Internal API: Join record ========== */ void semanage_user_key_unpack(const semanage_user_key_t * key, const char **name); int semanage_user_join(semanage_handle_t * handle, const semanage_user_base_t * record1, const semanage_user_extra_t * record2, semanage_user_t ** result); 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-3.8.1/src/user_record.c000066400000000000000000000214021476211737200172520ustar00rootroot00000000000000/* 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); } 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); } void semanage_user_key_free(semanage_user_key_t * key) { sepol_user_key_free(key); } 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); } int semanage_user_compare2(const semanage_user_t * user, const semanage_user_t * user2) { return strcmp(user->name, user2->name); } static int semanage_user_compare2_qsort(const void *p1, const void *p2) { const semanage_user_t *const *user1 = p1; const semanage_user_t *const *user2 = p2; return semanage_user_compare2(*user1, *user2); } /* Name */ const char *semanage_user_get_name(const semanage_user_t * user) { return user->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; } /* 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); } 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); } const char *semanage_user_get_mlsrange(const semanage_user_t * user) { return semanage_user_base_get_mlsrange(user->base); } 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); } /* 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); } 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); } 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; } 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; } 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); } /* Join properties */ 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; } 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 */ const 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-3.8.1/src/users_base_file.c000066400000000000000000000116671476211737200201040ustar00rootroot00000000000000/* 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, const 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; char *str = NULL; const 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) < 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((unsigned char)*(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((unsigned char)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) < 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; if (parse_fetch_string(handle, info, &str, ';', 1) < 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 */ static const 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 *path_ro, const char *path_rw, dbase_config_t * dconfig) { if (dbase_file_init(handle, path_ro, path_rw, &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-3.8.1/src/users_base_policydb.c000066400000000000000000000043601476211737200207620ustar00rootroot00000000000000/* * 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" #include "semanage_store.h" /* USER BASE record: POLICYDB extension: method table */ static const 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, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL), semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), &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-3.8.1/src/users_extra_file.c000066400000000000000000000055601476211737200203100ustar00rootroot00000000000000/* 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, const 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) < 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, ';', 1) < 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 */ static const 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 *path_ro, const char *path_rw, dbase_config_t * dconfig) { if (dbase_file_init(handle, path_ro, path_rw, &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-3.8.1/src/users_join.c000066400000000000000000000022631476211737200171220ustar00rootroot00000000000000/* 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 */ static const 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-3.8.1/src/users_local.c000066400000000000000000000055421476211737200172600ustar00rootroot00000000000000/* 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 < count; i++) { sename = semanage_seuser_get_sename(records[i]); if (strcmp(name, sename) == 0) { errno = EINVAL; ERR(handle, "%s is being used by %s login record", sename, semanage_seuser_get_name(records[i])); rc = -1; } } for(i = 0; i < count; i++) semanage_seuser_free(records[i]); free(records); semanage_user_free(user); if (rc) errno = EINVAL; return rc; } int semanage_user_del_local(semanage_handle_t * handle, const semanage_user_key_t * key) { if (lookup_seuser(handle, key)) return -1; dbase_config_t *dconfig = semanage_user_dbase_local(handle); return dbase_del(handle, dconfig, key); } int semanage_user_query_local(semanage_handle_t * handle, const semanage_user_key_t * key, semanage_user_t ** response) { dbase_config_t *dconfig = semanage_user_dbase_local(handle); return dbase_query(handle, dconfig, key, response); } int semanage_user_exists_local(semanage_handle_t * handle, const semanage_user_key_t * key, int *response) { dbase_config_t *dconfig = semanage_user_dbase_local(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_user_count_local(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_user_dbase_local(handle); return dbase_count(handle, dconfig, response); } int semanage_user_iterate_local(semanage_handle_t * handle, int (*handler) (const semanage_user_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_user_dbase_local(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_user_list_local(semanage_handle_t * handle, semanage_user_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_user_dbase_local(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-3.8.1/src/users_policy.c000066400000000000000000000026471476211737200174700ustar00rootroot00000000000000/* 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 "user_internal.h" #include "handle.h" #include "database.h" int semanage_user_query(semanage_handle_t * handle, const semanage_user_key_t * key, semanage_user_t ** response) { dbase_config_t *dconfig = semanage_user_dbase_policy(handle); return dbase_query(handle, dconfig, key, response); } int semanage_user_exists(semanage_handle_t * handle, const semanage_user_key_t * key, int *response) { dbase_config_t *dconfig = semanage_user_dbase_policy(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_user_count(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_user_dbase_policy(handle); return dbase_count(handle, dconfig, response); } int semanage_user_iterate(semanage_handle_t * handle, int (*handler) (const semanage_user_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_user_dbase_policy(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_user_list(semanage_handle_t * handle, semanage_user_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_user_dbase_policy(handle); return dbase_list(handle, dconfig, records, count); } libsemanage-3.8.1/src/utilities.c000066400000000000000000000160171476211737200167570ustar00rootroot00000000000000/* Author: Mark Goldman * 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 char *semanage_findval(const char *file, const char *var, const char *delim) { FILE *fd; char *buff = NULL; char *retval = NULL; size_t buff_len = 0; assert(file); assert(var); if ((fd = fopen(file, "re")) == 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 0; } if (!prefix) { return 1; } 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 *const seps = "\f\n\r\t\v "; size_t off = 0; if (!str) return NULL; /* skip one token and the spaces before and after it */ off = strspn(str, seps); off += strcspn(str + off, seps); off += strspn(str + off, seps); return strdup(str + off); } char *semanage_split(const char *str, const char *delim) { const char *retval; if (!str) return NULL; if (!delim || !(*delim)) return semanage_split_on_space(str); retval = strstr(str, delim); if (retval == NULL) return NULL; return strdup(retval + strlen(delim)); } int semanage_list_push(semanage_list_t ** list, const 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, const 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 || !(*l)->next) 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 *), 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 void *x, const void *y) { const semanage_list_t *const *l1 = x; const semanage_list_t *const *l2 = y; return strcmp((*l1)->data, (*l2)->data); } size_t semanage_str_count(const char *data, char what) { size_t count = 0; if (!data) return 0; while (*data) { if (*data == what) ++count; ++data; } return count; } void semanage_rtrim(char *str, char trim_to) { size_t len; if (!str) return; len = strlen(str); while (len > 0) { if (str[--len] == trim_to) { str[len] = '\0'; return; } } } char *semanage_str_replace(const char *search, const char *replace, const char *src, size_t lim) { size_t count = 0, slen, rlen, newsize; char *p, *pres, *result; const char *psrc; slen = strlen(search); rlen = strlen(replace); /* Do not support empty search strings */ if (slen == 0) return NULL; /* Count the occurrences of search in src and compute the new size */ for (p = strstr(src, search); p != NULL; p = strstr(p + slen, search)) { count++; if (lim && count >= lim) break; } if (!count) return strdup(src); /* Allocate the result string */ newsize = strlen(src) + 1 + count * (rlen - slen); result = malloc(newsize); if (!result) return NULL; /* Fill the result */ psrc = src; pres = result; for (p = strstr(src, search); p != NULL; p = strstr(psrc, search)) { /* Copy the part which has not been modified */ if (p != psrc) { size_t length = (size_t)(p - psrc); memcpy(pres, psrc, length); pres += length; } /* Copy the replacement part */ if (rlen != 0) { memcpy(pres, replace, rlen); pres += rlen; } psrc = p + slen; count--; if (!count) break; } /* Copy the last part, after doing a sanity check */ assert(pres + strlen(psrc) + 1 == result + newsize); strcpy(pres, psrc); return result; } /* 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 */ static 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; } int write_full(int fd, const void *buf, size_t len) { ssize_t w; const unsigned char *p = buf; while (len > 0) { w = write(fd, p, len); if (w == -1) { if (errno == EINTR) continue; return -1; } p += w; len -= (size_t)w; } return 0; } libsemanage-3.8.1/src/utilities.h000066400000000000000000000130341476211737200167600ustar00rootroot00000000000000/* 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(const char *file, const char *var, const 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 characters 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 characters that can be * a delimiter. * if *delim == '\0' behaves as semanage_splitOnSpace() * @return a ptr to the first character 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, const 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, const 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 void *x, const void *y); /** * @param data a target string * @param what a character * @returns the number of times the char appears in the string */ size_t semanage_str_count(const char *data, char what); /** * @param - a string * @param the character to trim to * @return - mangles the string, converting the first * occurrence of the character to a '\0' from * the end of the string. */ void semanage_rtrim(char *str, char trim_to); /** * @param value being searched for * @param replacement value that replaces found search values * @param string being searched and replaced on * @param maximum number of value occurrences (zero for unlimited) * @return newly-allocated string with the replaced values */ char *semanage_str_replace(const char *search, const char *replace, const char *src, size_t lim); /** * @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; /** * Wrapper around write(2), which retries on short writes. * * @param fd file descriptor to write to * @param buf buffer to be written * @param len number of bytes to be written from buffer * * @return 0 on success, -1 else (with errno set) */ int write_full(int fd, const void *buf, size_t len) WARN_UNUSED; #endif libsemanage-3.8.1/tests/000077500000000000000000000000001476211737200151465ustar00rootroot00000000000000libsemanage-3.8.1/tests/.gitignore000066400000000000000000000000331476211737200171320ustar00rootroot00000000000000libsemanage-tests *.policy libsemanage-3.8.1/tests/Makefile000066400000000000000000000013331476211737200166060ustar00rootroot00000000000000# Add your test source files here: SOURCES = $(sort $(wildcard *.c)) CILS = $(sort $(wildcard *.cil)) ########################################################################### EXECUTABLE = libsemanage-tests CFLAGS += -g -O0 -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute override CFLAGS += -I../src -I../include override LDLIBS += -lcunit -lbz2 -laudit -lselinux -lsepol OBJECTS = $(SOURCES:.c=.o) POLICIES = $(CILS:.cil=.policy) all: $(EXECUTABLE) $(POLICIES) $(EXECUTABLE): $(OBJECTS) ../src/libsemanage.a $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) %.policy: %.cil ../../secilc/secilc $*.cil -o $*.policy -f /dev/null clean distclean: rm -rf $(OBJECTS) $(POLICIES) $(EXECUTABLE) test: all ./$(EXECUTABLE) libsemanage-3.8.1/tests/README000066400000000000000000000044021476211737200160260ustar00rootroot00000000000000Notes 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-3.8.1/tests/libsemanage-tests.c000066400000000000000000000064341476211737200207300ustar00rootroot00000000000000/* 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 "test_handle.h" #include "test_bool.h" #include "test_fcontext.h" #include "test_iface.h" #include "test_ibendport.h" #include "test_node.h" #include "test_port.h" #include "test_user.h" #include "test_other.h" #include #include #include #include #include #include #include #define DECLARE_SUITE(name) \ do { \ 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(); \ } \ } while (0) 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 bool do_tests(int interactive, int verbose) { CU_pSuite suite = NULL; unsigned int num_failures; /* Initialize the CUnit test registry. */ if (CUE_SUCCESS != CU_initialize_registry()) return CU_get_error(); DECLARE_SUITE(semanage_store); DECLARE_SUITE(semanage_utilities); DECLARE_SUITE(handle); DECLARE_SUITE(boolean); DECLARE_SUITE(fcontext); DECLARE_SUITE(iface); DECLARE_SUITE(ibendport); DECLARE_SUITE(node); DECLARE_SUITE(port); DECLARE_SUITE(user); DECLARE_SUITE(other); 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(); num_failures = CU_get_number_of_tests_failed(); CU_cleanup_registry(); return CU_get_error() == CUE_SUCCESS && num_failures == 0; } /* 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-3.8.1/tests/nc_sort_malformed000066400000000000000000000022161476211737200205670ustar00rootroot00000000000000pre *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-3.8.1/tests/nc_sort_sorted000066400000000000000000000020461476211737200201220ustar00rootroot00000000000000*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-3.8.1/tests/nc_sort_unsorted000066400000000000000000000022651476211737200204700ustar00rootroot00000000000000pre *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-3.8.1/tests/test_bool.c000066400000000000000000000555671476211737200173260ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 "utilities.h" #include "test_bool.h" #define BOOL_COUNT 3 #define BOOL1_NAME "first_bool" #define BOOL1_VALUE 1 #define BOOL2_NAME "second_bool" #define BOOL2_VALUE 0 #define BOOL3_NAME "third_bool" #define BOOL3_VALUE 0 #define BOOL_NONEXISTENT "asdf" /* boolean_record.h */ static void test_bool_key_create(void); static void test_bool_key_extract(void); static void test_bool_compare(void); static void test_bool_compare2(void); static void test_bool_get_set_name(void); static void test_bool_get_set_value(void); static void test_bool_create(void); static void test_bool_clone(void); /* booleans_policy.h */ static void test_bool_query(void); static void test_bool_exists(void); static void test_bool_count(void); static void test_bool_iterate(void); static void test_bool_list(void); /* booleans_local.h */ static void test_bool_modify_del_local(void); static void test_bool_query_local(void); static void test_bool_exists_local(void); static void test_bool_count_local(void); static void test_bool_iterate_local(void); static void test_bool_list_local(void); int boolean_test_init(void) { if (create_test_store() < 0) { fprintf(stderr, "Could not create test store\n"); return 1; } if (write_test_policy_from_file("test_bool.policy") < 0) { fprintf(stderr, "Could not write test policy\n"); return 1; } return 0; } int boolean_test_cleanup(void) { if (destroy_test_store() < 0) { fprintf(stderr, "Could not destroy test store\n"); return 1; } return 0; } int boolean_add_tests(CU_pSuite suite) { CU_add_test(suite, "bool_key_create", test_bool_key_create); CU_add_test(suite, "bool_key_extract", test_bool_key_extract); CU_add_test(suite, "bool_compare", test_bool_compare); CU_add_test(suite, "bool_compare2", test_bool_compare2); CU_add_test(suite, "bool_get_set_name", test_bool_get_set_name); CU_add_test(suite, "bool_get_set_value", test_bool_get_set_value); CU_add_test(suite, "bool_create", test_bool_create); CU_add_test(suite, "bool_clone", test_bool_clone); CU_add_test(suite, "bool_query", test_bool_query); CU_add_test(suite, "bool_exists", test_bool_exists); CU_add_test(suite, "bool_count", test_bool_count); CU_add_test(suite, "bool_iterate", test_bool_iterate); CU_add_test(suite, "bool_list", test_bool_list); CU_add_test(suite, "bool_modify_del_local", test_bool_modify_del_local); CU_add_test(suite, "bool_query_local", test_bool_query_local); CU_add_test(suite, "bool_exists_local", test_bool_exists_local); CU_add_test(suite, "bool_count_local", test_bool_count_local); CU_add_test(suite, "bool_iterate_local", test_bool_iterate_local); CU_add_test(suite, "bool_list_local", test_bool_list_local); return 0; } /* Helpers */ static semanage_bool_t *get_bool_nth(int idx) { int res; semanage_bool_t **records; semanage_bool_t *boolean; unsigned int count; if (idx == I_NULL) return NULL; res = semanage_bool_list(sh, &records, &count); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_FATAL(count >= (unsigned int) idx + 1); boolean = records[idx]; for (unsigned int i = 0; i < count; i++) if (i != (unsigned int) idx) semanage_bool_free(records[i]); free(records); return boolean; } static semanage_bool_t *get_bool_new(void) { int res; semanage_bool_t *boolean; res = semanage_bool_create(sh, &boolean); CU_ASSERT_FATAL(res >= 0); return boolean; } static semanage_bool_key_t *get_bool_key_nth(int idx) { semanage_bool_key_t *key; semanage_bool_t *boolean; int res; if (idx == I_NULL) return NULL; boolean = get_bool_nth(idx); res = semanage_bool_key_extract(sh, boolean, &key); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); semanage_bool_free(boolean); return key; } static semanage_bool_key_t *get_bool_key_from_str(const char *str) { semanage_bool_key_t *key; int res; if (str == NULL) return NULL; res = semanage_bool_key_create(sh, str, &key); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); return key; } static void add_local_bool(const char *name) { semanage_bool_t *boolean; semanage_bool_key_t *key = NULL; CU_ASSERT_PTR_NOT_NULL_FATAL(name); CU_ASSERT_FATAL(semanage_bool_key_create(sh, name, &key) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); CU_ASSERT_FATAL(semanage_bool_query(sh, key, &boolean) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(boolean); CU_ASSERT_FATAL(semanage_bool_modify_local(sh, key, boolean) >= 0); semanage_bool_key_free(key); semanage_bool_free(boolean); } static void delete_local_bool(const char *name) { semanage_bool_key_t *key = NULL; CU_ASSERT_PTR_NOT_NULL_FATAL(name); CU_ASSERT_FATAL(semanage_bool_key_create(sh, name, &key) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); CU_ASSERT_FATAL(semanage_bool_del_local(sh, key) >= 0); semanage_bool_key_free(key); } /* Function bool_key_create */ static void helper_bool_key_create(level_t level) { semanage_bool_key_t *key = NULL; setup_handle(level); CU_ASSERT(semanage_bool_key_create(sh, "", &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); semanage_bool_key_free(key); key = NULL; CU_ASSERT(semanage_bool_key_create(sh, "testbool", &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); semanage_bool_key_free(key); cleanup_handle(level); } void test_bool_key_create(void) { helper_bool_key_create(SH_CONNECT); helper_bool_key_create(SH_TRANS); } /* Function bool_key_extract */ #define SK_NULL 1 #define SK_NEW 2 #define SK_INDEX 3 #define SK_KEY_NULL 4 static void helper_bool_key_extract(level_t level, int mode) { semanage_bool_t *boolean = NULL; semanage_bool_key_t *key = NULL; int res; setup_handle(level); switch (mode) { case SK_NULL: boolean = NULL; break; case SK_NEW: boolean = get_bool_new(); break; case SK_INDEX: boolean = get_bool_nth(0); break; case SK_KEY_NULL: boolean = get_bool_nth(0); break; default: CU_FAIL_FATAL("Invalid mode\n"); } if (mode == SK_KEY_NULL) res = semanage_bool_key_extract(sh, boolean, NULL); else res = semanage_bool_key_extract(sh, boolean, &key); CU_ASSERT(res >= 0); res = semanage_bool_compare(boolean, key); CU_ASSERT(res == 0); semanage_bool_key_free(key); semanage_bool_free(boolean); cleanup_handle(level); } void test_bool_key_extract(void) { helper_bool_key_extract(SH_CONNECT, SK_INDEX); helper_bool_key_extract(SH_TRANS, SK_INDEX); } #undef SK_NULL #undef SK_NEW #undef SK_INDEX #undef SK_KEY_NULL /* Function bool_compare */ static void helper_bool_compare(level_t level, int bool_idx1, int bool_idx2) { semanage_bool_t *boolean; semanage_bool_key_t *key; int res; setup_handle(level); boolean = get_bool_nth(bool_idx1); key = get_bool_key_nth(bool_idx2); res = semanage_bool_compare(boolean, key); if (bool_idx1 == bool_idx2) { CU_ASSERT(res == 0); } else { CU_ASSERT(res != 0); } semanage_bool_free(boolean); semanage_bool_key_free(key); cleanup_handle(level); } static void test_bool_compare(void) { helper_bool_compare(SH_CONNECT, I_FIRST, I_FIRST); helper_bool_compare(SH_CONNECT, I_FIRST, I_SECOND); helper_bool_compare(SH_CONNECT, I_SECOND, I_FIRST); helper_bool_compare(SH_CONNECT, I_SECOND, I_SECOND); helper_bool_compare(SH_TRANS, I_FIRST, I_FIRST); helper_bool_compare(SH_TRANS, I_FIRST, I_SECOND); helper_bool_compare(SH_TRANS, I_SECOND, I_FIRST); helper_bool_compare(SH_TRANS, I_SECOND, I_SECOND); } /* Function bool_compare2 */ static void helper_bool_compare2(level_t level, int bool_idx1, int bool_idx2) { semanage_bool_t *bool1; semanage_bool_t *bool2; int res; setup_handle(level); bool1 = get_bool_nth(bool_idx1); bool2 = get_bool_nth(bool_idx2); res = semanage_bool_compare2(bool1, bool2); if (bool_idx1 == bool_idx2) { CU_ASSERT(res == 0); } else { CU_ASSERT(res != 0); } semanage_bool_free(bool1); semanage_bool_free(bool2); cleanup_handle(level); } static void test_bool_compare2(void) { helper_bool_compare2(SH_CONNECT, I_FIRST, I_FIRST); helper_bool_compare2(SH_CONNECT, I_FIRST, I_SECOND); helper_bool_compare2(SH_CONNECT, I_SECOND, I_FIRST); helper_bool_compare2(SH_CONNECT, I_SECOND, I_SECOND); helper_bool_compare2(SH_TRANS, I_FIRST, I_FIRST); helper_bool_compare2(SH_TRANS, I_FIRST, I_SECOND); helper_bool_compare2(SH_TRANS, I_SECOND, I_FIRST); helper_bool_compare2(SH_TRANS, I_SECOND, I_SECOND); } /* Function bool_get_name, bool_set_name */ static void helper_bool_get_set_name(level_t level, int bool_idx, const char *name) { semanage_bool_t *boolean; const char *new_name = NULL; setup_handle(level); boolean = get_bool_nth(bool_idx); CU_ASSERT(semanage_bool_set_name(sh, boolean, name) >= 0); new_name = semanage_bool_get_name(boolean); CU_ASSERT_PTR_NOT_NULL(new_name); /* Use assert to silence the clang analyzer */ assert(new_name); CU_ASSERT_STRING_EQUAL(new_name, name); semanage_bool_free(boolean); cleanup_handle(level); } static void test_bool_get_set_name(void) { helper_bool_get_set_name(SH_CONNECT, I_FIRST, "testbool"); helper_bool_get_set_name(SH_CONNECT, I_FIRST, ""); helper_bool_get_set_name(SH_CONNECT, I_SECOND, "testbool"); helper_bool_get_set_name(SH_CONNECT, I_SECOND, ""); helper_bool_get_set_name(SH_TRANS, I_FIRST, "testbool"); helper_bool_get_set_name(SH_TRANS, I_FIRST, ""); helper_bool_get_set_name(SH_TRANS, I_SECOND, "testbool"); helper_bool_get_set_name(SH_TRANS, I_SECOND, ""); } /* Function bool_get_value, bool_set_value */ static void helper_bool_get_set_value(int bool_idx, int val) { semanage_bool_t *boolean; int new_val = 0; setup_handle(SH_CONNECT); boolean = get_bool_nth(bool_idx); cleanup_handle(SH_CONNECT); semanage_bool_set_value(boolean, val); new_val = semanage_bool_get_value(boolean); CU_ASSERT(new_val == val); semanage_bool_free(boolean); } static void test_bool_get_set_value(void) { helper_bool_get_set_value(I_FIRST, 1); helper_bool_get_set_value(I_FIRST, 0); helper_bool_get_set_value(I_SECOND, 1); helper_bool_get_set_value(I_SECOND, 0); } /* Function bool_create */ static void helper_bool_create(level_t level) { semanage_bool_t *boolean; setup_handle(level); CU_ASSERT(semanage_bool_create(sh, &boolean) >= 0); CU_ASSERT_PTR_NULL(semanage_bool_get_name(boolean)); CU_ASSERT(semanage_bool_get_value(boolean) == 0); semanage_bool_free(boolean); cleanup_handle(level); } static void test_bool_create(void) { helper_bool_create(SH_HANDLE); helper_bool_create(SH_CONNECT); helper_bool_create(SH_TRANS); } /* Function bool_clone */ static void helper_bool_clone(level_t level, int bool_idx) { semanage_bool_t *boolean; semanage_bool_t *boolean_clone; const char *str; const char *str_clone; int val; int val_clone; setup_handle(level); boolean = get_bool_nth(bool_idx); CU_ASSERT(semanage_bool_clone(sh, boolean, &boolean_clone) >= 0); str = semanage_bool_get_name(boolean); str_clone = semanage_bool_get_name(boolean_clone); CU_ASSERT_STRING_EQUAL(str, str_clone); val = semanage_bool_get_value(boolean); val_clone = semanage_bool_get_value(boolean_clone); CU_ASSERT_EQUAL(val, val_clone); semanage_bool_free(boolean_clone); semanage_bool_free(boolean); cleanup_handle(level); } static void test_bool_clone(void) { helper_bool_clone(SH_CONNECT, I_FIRST); helper_bool_clone(SH_CONNECT, I_SECOND); helper_bool_clone(SH_TRANS, I_FIRST); helper_bool_clone(SH_TRANS, I_SECOND); } /* Function bool_query */ static void helper_bool_query(level_t level, const char *bool_str, int exp_res) { semanage_bool_key_t *key; semanage_bool_t *resp = (void *) 42; setup_handle(level); key = get_bool_key_from_str(bool_str); CU_ASSERT(semanage_bool_query(sh, key, &resp) >= 0); if (exp_res >= 0) { const char *name = semanage_bool_get_name(resp); CU_ASSERT_STRING_EQUAL(name, bool_str); } else { CU_ASSERT_PTR_NULL(resp); } semanage_bool_free(resp); semanage_bool_key_free(key); cleanup_handle(level); } static void test_bool_query(void) { helper_bool_query(SH_CONNECT, BOOL1_NAME, 1); helper_bool_query(SH_CONNECT, BOOL2_NAME, 1); helper_bool_query(SH_CONNECT, BOOL_NONEXISTENT, -1); helper_bool_query(SH_TRANS, BOOL1_NAME, 1); helper_bool_query(SH_TRANS, BOOL2_NAME, 1); helper_bool_query(SH_TRANS, BOOL_NONEXISTENT, -1); } /* Function bool_exists */ static void helper_bool_exists(level_t level, const char *bool_str, int exp_resp) { semanage_bool_key_t *key; int resp; setup_handle(level); key = get_bool_key_from_str(bool_str); CU_ASSERT(semanage_bool_exists(sh, key, &resp) >= 0); CU_ASSERT(resp == exp_resp); semanage_bool_key_free(key); cleanup_handle(level); } static void test_bool_exists(void) { helper_bool_exists(SH_CONNECT, BOOL1_NAME, 1); helper_bool_exists(SH_CONNECT, BOOL2_NAME, 1); helper_bool_exists(SH_CONNECT, BOOL_NONEXISTENT, 0); helper_bool_exists(SH_TRANS, BOOL1_NAME, 1); helper_bool_exists(SH_TRANS, BOOL2_NAME, 1); helper_bool_exists(SH_TRANS, BOOL_NONEXISTENT, 0); } /* Function bool_count */ static void test_bool_count(void) { unsigned int resp; /* handle */ setup_handle(SH_HANDLE); CU_ASSERT(semanage_bool_count(sh, &resp) < 0); CU_ASSERT(semanage_bool_count(sh, NULL) < 0); cleanup_handle(SH_HANDLE); /* connect */ resp = 0; setup_handle(SH_CONNECT); CU_ASSERT(semanage_bool_count(sh, &resp) >= 0); CU_ASSERT(resp == BOOL_COUNT); cleanup_handle(SH_CONNECT); /* trans */ resp = 0; setup_handle(SH_TRANS); CU_ASSERT(semanage_bool_count(sh, &resp) >= 0); CU_ASSERT(resp == BOOL_COUNT); cleanup_handle(SH_TRANS); } /* Function bool_iterate */ static unsigned int counter_bool_iterate = 0; static int handler_bool_iterate(__attribute__((unused)) const semanage_bool_t *record, __attribute__((unused)) void *varg) { counter_bool_iterate++; return 0; } static void helper_bool_iterate_invalid(void) { setup_handle(SH_HANDLE); CU_ASSERT(semanage_bool_iterate(sh, &handler_bool_iterate, NULL) < 0); CU_ASSERT(semanage_bool_iterate(sh, NULL, NULL) < 0); cleanup_handle(SH_HANDLE); } static void helper_bool_iterate(level_t level) { setup_handle(level); counter_bool_iterate = 0; CU_ASSERT(semanage_bool_iterate(sh, &handler_bool_iterate, NULL) >= 0); CU_ASSERT(counter_bool_iterate == BOOL_COUNT); cleanup_handle(level); } static void test_bool_iterate(void) { helper_bool_iterate_invalid(); helper_bool_iterate(SH_CONNECT); helper_bool_iterate(SH_TRANS); } /* Function bool_list */ static void helper_bool_list_invalid(void) { semanage_bool_t **records; unsigned int count; setup_handle(SH_HANDLE); CU_ASSERT(semanage_bool_list(sh, &records, &count) < 0); CU_ASSERT(semanage_bool_list(sh, NULL, &count) < 0); CU_ASSERT(semanage_bool_list(sh, &records, NULL) < 0); cleanup_handle(SH_HANDLE); } static void helper_bool_list(level_t level) { semanage_bool_t **records; unsigned int count; setup_handle(level); CU_ASSERT(semanage_bool_list(sh, &records, &count) >= 0); CU_ASSERT(count == BOOL_COUNT); for (unsigned int i = 0; i < count; i++) CU_ASSERT_PTR_NOT_NULL(records[i]); for (unsigned int i = 0; i < count; i++) semanage_bool_free(records[i]); free(records); cleanup_handle(level); } static void test_bool_list(void) { helper_bool_list_invalid(); helper_bool_list(SH_CONNECT); helper_bool_list(SH_TRANS); } /* Function bool_modify_local, bool_del_local */ static void helper_bool_modify_del_local(level_t level, const char *name, int old_val, int exp_res) { semanage_bool_t *boolean; semanage_bool_t *boolean_local = NULL; semanage_bool_key_t *key = NULL; int res; int new_val; /* setup */ setup_handle(level); CU_ASSERT(semanage_bool_key_create(sh, name, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); CU_ASSERT(semanage_bool_query(sh, key, &boolean) >= 0); CU_ASSERT_PTR_NOT_NULL(boolean); new_val = !old_val; semanage_bool_set_value(boolean, new_val); /* test */ res = semanage_bool_modify_local(sh, key, boolean); if (exp_res < 0) { CU_ASSERT(res < 0); } else { CU_ASSERT(res >= 0); /* write changes to file */ if (level == SH_TRANS) { helper_commit(); helper_begin_transaction(); } CU_ASSERT(semanage_bool_query_local(sh, key, &boolean_local) >= 0); CU_ASSERT(semanage_bool_compare2(boolean_local, boolean) == 0); semanage_bool_free(boolean_local); CU_ASSERT(semanage_bool_del_local(sh, key) >= 0); CU_ASSERT(semanage_bool_query_local(sh, key, &boolean_local) < 0); } /* cleanup */ semanage_bool_key_free(key); semanage_bool_free(boolean); cleanup_handle(level); } static void test_bool_modify_del_local(void) { helper_bool_modify_del_local(SH_CONNECT, BOOL1_NAME, BOOL1_VALUE, -1); helper_bool_modify_del_local(SH_CONNECT, BOOL2_NAME, BOOL2_VALUE, -1); helper_bool_modify_del_local(SH_TRANS, BOOL1_NAME, BOOL1_VALUE, 1); helper_bool_modify_del_local(SH_TRANS, BOOL2_NAME, BOOL2_VALUE, 1); } /* Function bool_query_local */ static void test_bool_query_local(void) { semanage_bool_key_t *key = NULL; semanage_bool_t *resp = NULL; /* connect */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_bool_key_create(sh, BOOL1_NAME, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); CU_ASSERT(semanage_bool_query_local(sh, key, &resp) < 0); CU_ASSERT_PTR_NULL(resp); cleanup_handle(SH_CONNECT); /* transaction */ setup_handle(SH_TRANS); semanage_bool_key_free(key); CU_ASSERT(semanage_bool_key_create(sh, BOOL1_NAME, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); CU_ASSERT(semanage_bool_query_local(sh, key, &resp) < 0); CU_ASSERT_PTR_NULL(resp); semanage_bool_free(resp); add_local_bool(BOOL1_NAME); CU_ASSERT(semanage_bool_query_local(sh, key, &resp) >= 0); CU_ASSERT_PTR_NOT_NULL(resp); semanage_bool_free(resp); semanage_bool_key_free(key); CU_ASSERT(semanage_bool_key_create(sh, BOOL2_NAME, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); add_local_bool(BOOL2_NAME); CU_ASSERT(semanage_bool_query_local(sh, key, &resp) >= 0); CU_ASSERT_PTR_NOT_NULL(resp); semanage_bool_free(resp); /* cleanup */ semanage_bool_key_free(key); delete_local_bool(BOOL1_NAME); delete_local_bool(BOOL2_NAME); cleanup_handle(SH_TRANS); } /* Function bool_exists_local */ static void test_bool_exists_local(void) { int resp = -1; semanage_bool_key_t *key; /* setup */ setup_handle(SH_TRANS); CU_ASSERT(semanage_bool_key_create(sh, BOOL1_NAME, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* test */ CU_ASSERT(semanage_bool_exists_local(sh, key, &resp) >= 0); CU_ASSERT(resp == 0); add_local_bool(BOOL1_NAME); resp = -1; CU_ASSERT(semanage_bool_exists_local(sh, key, &resp) >= 0); CU_ASSERT(resp == 1); delete_local_bool(BOOL1_NAME); resp = -1; CU_ASSERT(semanage_bool_exists_local(sh, key, &resp) >= 0); CU_ASSERT(resp == 0); /* cleanup */ semanage_bool_key_free(key); cleanup_handle(SH_TRANS); } /* Function bool_count_local */ static void test_bool_count_local(void) { unsigned int resp; unsigned int init_count; /* handle */ setup_handle(SH_HANDLE); CU_ASSERT(semanage_bool_count_local(sh, &resp) < 0); cleanup_handle(SH_HANDLE); /* connect */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_bool_count_local(sh, &resp) >= 0); cleanup_handle(SH_CONNECT); /* transaction */ setup_handle(SH_TRANS); CU_ASSERT(semanage_bool_count_local(sh, &resp) >= 0); init_count = resp; add_local_bool(BOOL1_NAME); CU_ASSERT(semanage_bool_count_local(sh, &resp) >= 0); CU_ASSERT(resp == init_count + 1); add_local_bool(BOOL2_NAME); CU_ASSERT(semanage_bool_count_local(sh, &resp) >= 0); CU_ASSERT(resp == init_count + 2); delete_local_bool(BOOL2_NAME); CU_ASSERT(semanage_bool_count_local(sh, &resp) >= 0); CU_ASSERT(resp == init_count + 1); delete_local_bool(BOOL1_NAME); CU_ASSERT(semanage_bool_count_local(sh, &resp) >= 0); CU_ASSERT(resp == init_count); /* cleanup */ cleanup_handle(SH_TRANS); } /* Function bool_iterate_local */ static unsigned int counter_bool_iterate_local = 0; static int handler_bool_iterate_local(__attribute__((unused)) const semanage_bool_t *record, __attribute__((unused)) void *varg) { counter_bool_iterate_local++; return 0; } static void test_bool_iterate_local(void) { unsigned int init_count; /* handle */ setup_handle(SH_HANDLE); CU_ASSERT(semanage_bool_iterate_local(sh, &handler_bool_iterate_local, NULL) < 0); cleanup_handle(SH_HANDLE); /* connect */ setup_handle(SH_CONNECT); counter_bool_iterate_local = 0; CU_ASSERT(semanage_bool_iterate_local(sh, &handler_bool_iterate_local, NULL) >= 0); init_count = counter_bool_iterate_local; cleanup_handle(SH_CONNECT); /* transaction */ setup_handle(SH_TRANS); counter_bool_iterate_local = 0; CU_ASSERT(semanage_bool_iterate_local(sh, &handler_bool_iterate_local, NULL) >= 0); CU_ASSERT(counter_bool_iterate_local == init_count); add_local_bool(BOOL1_NAME); counter_bool_iterate_local = 0; CU_ASSERT(semanage_bool_iterate_local(sh, &handler_bool_iterate_local, NULL) >= 0); CU_ASSERT(counter_bool_iterate_local == init_count + 1); add_local_bool(BOOL2_NAME); counter_bool_iterate_local = 0; CU_ASSERT(semanage_bool_iterate_local(sh, &handler_bool_iterate_local, NULL) >= 0); CU_ASSERT(counter_bool_iterate_local == init_count + 2); /* cleanup */ delete_local_bool(BOOL1_NAME); delete_local_bool(BOOL2_NAME); cleanup_handle(SH_TRANS); } /* Function bool_list_local */ static void test_bool_list_local(void) { semanage_bool_t **records; unsigned int count; unsigned int init_count; /* handle */ setup_handle(SH_HANDLE); CU_ASSERT(semanage_bool_list_local(sh, &records, &count) < 0); CU_ASSERT(semanage_bool_list_local(sh, NULL, &count) < 0); CU_ASSERT(semanage_bool_list_local(sh, &records, NULL) < 0); cleanup_handle(SH_HANDLE); /* connect */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_bool_list_local(sh, &records, &count) >= 0); init_count = count; cleanup_handle(SH_CONNECT); /* transaction */ setup_handle(SH_TRANS); CU_ASSERT(semanage_bool_list_local(sh, &records, &count) >= 0); CU_ASSERT(count == init_count); add_local_bool(BOOL1_NAME); CU_ASSERT(semanage_bool_list_local(sh, &records, &count) >= 0); CU_ASSERT(count == init_count + 1); CU_ASSERT_PTR_NOT_NULL(records[0]); semanage_bool_free(records[0]); free(records); add_local_bool(BOOL2_NAME); CU_ASSERT(semanage_bool_list_local(sh, &records, &count) >= 0); CU_ASSERT(count == init_count + 2); CU_ASSERT_PTR_NOT_NULL(records[0]); CU_ASSERT_PTR_NOT_NULL(records[1]); semanage_bool_free(records[0]); semanage_bool_free(records[1]); free(records); /* cleanup */ delete_local_bool(BOOL1_NAME); delete_local_bool(BOOL2_NAME); cleanup_handle(SH_TRANS); } libsemanage-3.8.1/tests/test_bool.cil000066400000000000000000000011751476211737200176350ustar00rootroot00000000000000(typeattribute cil_gen_require) (roleattribute cil_gen_require) (handleunknown allow) (mls true) (policycap network_peer_controls) (policycap open_perms) (sid security) (sidorder (security)) (sensitivity s0) (sensitivityorder (s0)) (user system_u) (userrole system_u object_r) (userlevel system_u (s0)) (userrange system_u ((s0) (s0))) (role object_r) (roletype object_r test_t) (type test_t) (sidcontext security (system_u object_r test_t ((s0) (s0)))) (class test_class (test_perm)) (classorder (test_class)) (allow test_t self (test_class (test_perm))) (boolean first_bool true) (boolean second_bool false) (boolean third_bool false) libsemanage-3.8.1/tests/test_bool.h000066400000000000000000000020261476211737200173110ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 __TEST_BOOL_H__ #define __TEST_BOOL_H__ #include #include "semanage/semanage.h" int boolean_test_init(void); int boolean_test_cleanup(void); int boolean_add_tests(CU_pSuite suite); #endif libsemanage-3.8.1/tests/test_fcontext.c000066400000000000000000000664621476211737200202210ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 "utilities.h" #include "test_fcontext.h" static const char FCONTEXTS[] = "/etc/selinux(/.*) -s system_u:object_r:first_t:s0\n" "/etc/selinux/targeted -- system_u:object_r:second_t:s0\n" "/etc/selinux(/.*) -b system_u:object_r:third_t:s0\n"; static const unsigned int FCONTEXTS_LEN = sizeof(FCONTEXTS); #define FCONTEXTS_COUNT 3 #define FCONTEXT1_EXPR "/etc/selinux(/.*)" #define FCONTEXT1_TYPE SEMANAGE_FCONTEXT_SOCK #define FCONTEXT2_EXPR "/etc/selinux/targeted" #define FCONTEXT2_TYPE SEMANAGE_FCONTEXT_REG #define FCONTEXT_NONEXISTENT_EXPR "/asdf" #define FCONTEXT_NONEXISTENT_TYPE SEMANAGE_FCONTEXT_ALL /* fcontext_record.h */ static void test_fcontext_compare(void); static void test_fcontext_compare2(void); static void test_fcontext_key_create(void); static void test_fcontext_key_extract(void); static void test_fcontext_get_set_expr(void); static void test_fcontext_get_set_type(void); static void test_fcontext_get_type_str(void); static void test_fcontext_get_set_con(void); static void test_fcontext_create(void); static void test_fcontext_clone(void); /* fcontext_policy.h */ static void test_fcontext_query(void); static void test_fcontext_exists(void); static void test_fcontext_count(void); static void test_fcontext_iterate(void); static void test_fcontext_list(void); /* fcontext_local.h */ static void test_fcontext_modify_del_local(void); static void test_fcontext_query_local(void); static void test_fcontext_exists_local(void); static void test_fcontext_count_local(void); static void test_fcontext_iterate_local(void); static void test_fcontext_list_local(void); static int write_file_contexts(const char *data, unsigned int data_len) { FILE *fptr = fopen("test-policy/store/active/file_contexts", "w+"); if (!fptr) { perror("fopen"); return -1; } if (fwrite(data, data_len, 1, fptr) != 1) { perror("fwrite"); fclose(fptr); return -1; } fclose(fptr); return 0; } int fcontext_test_init(void) { if (create_test_store() < 0) { fprintf(stderr, "Could not create test store\n"); return 1; } if (write_test_policy_from_file("test_fcontext.policy") < 0) { fprintf(stderr, "Could not write test policy\n"); return 1; } if (write_file_contexts(FCONTEXTS, FCONTEXTS_LEN) < 0) { fprintf(stderr, "Could not write file contexts\n"); return 1; } return 0; } int fcontext_test_cleanup(void) { if (destroy_test_store() < 0) { fprintf(stderr, "Could not destroy test store\n"); return 1; } return 0; } int fcontext_add_tests(CU_pSuite suite) { CU_add_test(suite, "test_fcontext_compare", test_fcontext_compare); CU_add_test(suite, "test_fcontext_compare2", test_fcontext_compare2); CU_add_test(suite, "test_fcontext_key_create", test_fcontext_key_create); CU_add_test(suite, "test_fcontext_key_extract", test_fcontext_key_extract); CU_add_test(suite, "test_fcontext_get_set_expr", test_fcontext_get_set_expr); CU_add_test(suite, "test_fcontext_get_set_type", test_fcontext_get_set_type); CU_add_test(suite, "test_fcontext_get_type_str", test_fcontext_get_type_str); CU_add_test(suite, "test_fcontext_get_set_con", test_fcontext_get_set_con); CU_add_test(suite, "test_fcontext_create", test_fcontext_create); CU_add_test(suite, "test_fcontext_clone", test_fcontext_clone); CU_add_test(suite, "test_fcontext_query", test_fcontext_query); CU_add_test(suite, "test_fcontext_exists", test_fcontext_exists); CU_add_test(suite, "test_fcontext_count", test_fcontext_count); CU_add_test(suite, "test_fcontext_iterate", test_fcontext_iterate); CU_add_test(suite, "test_fcontext_list", test_fcontext_list); CU_add_test(suite, "test_fcontext_modify_del_local", test_fcontext_modify_del_local); CU_add_test(suite, "test_fcontext_query_local", test_fcontext_query_local); CU_add_test(suite, "test_fcontext_exists_local", test_fcontext_exists_local); CU_add_test(suite, "test_fcontext_count_local", test_fcontext_count_local); CU_add_test(suite, "test_fcontext_iterate_local", test_fcontext_iterate_local); CU_add_test(suite, "test_fcontext_list_local", test_fcontext_list_local); return 0; } /* Helpers */ static semanage_fcontext_t *get_fcontext_nth(int idx) { semanage_fcontext_t **records; semanage_fcontext_t *fcontext; unsigned int count; if (idx == I_NULL) return NULL; CU_ASSERT_FATAL(semanage_fcontext_list(sh, &records, &count) >= 0); CU_ASSERT_FATAL(count >= (unsigned int) idx + 1); fcontext = records[idx]; for (unsigned int i = 0; i < count; i++) if (i != (unsigned int) idx) semanage_fcontext_free(records[i]); free(records); return fcontext; } static semanage_fcontext_key_t *get_fcontext_key_nth(int idx) { semanage_fcontext_key_t *key; semanage_fcontext_t *fcontext; if (idx == I_NULL) return NULL; fcontext = get_fcontext_nth(idx); CU_ASSERT_FATAL(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); semanage_fcontext_free(fcontext); return key; } static void add_local_fcontext(int fcontext_idx) { semanage_fcontext_t *fcontext; semanage_fcontext_key_t *key = NULL; CU_ASSERT_FATAL(fcontext_idx != I_NULL); fcontext = get_fcontext_nth(fcontext_idx); CU_ASSERT_FATAL(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); CU_ASSERT_FATAL(semanage_fcontext_modify_local(sh, key, fcontext) >= 0); /* cleanup */ semanage_fcontext_key_free(key); semanage_fcontext_free(fcontext); } static void delete_local_fcontext(int fcontext_idx) { semanage_fcontext_key_t *key = NULL; CU_ASSERT_FATAL(fcontext_idx != I_NULL); key = get_fcontext_key_nth(fcontext_idx); CU_ASSERT_FATAL(semanage_fcontext_del_local(sh, key) >= 0); semanage_fcontext_key_free(key); } static semanage_fcontext_key_t *get_fcontext_key_from_str(const char *str, int type) { semanage_fcontext_key_t *key; int res; if (str == NULL) return NULL; res = semanage_fcontext_key_create(sh, str, type, &key); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); return key; } /* Function semanage_fcontext_compare */ static void test_fcontext_compare(void) { semanage_fcontext_t *fcontext; semanage_fcontext_key_t *key1; semanage_fcontext_key_t *key2; semanage_fcontext_key_t *key3; /* setup */ setup_handle(SH_CONNECT); fcontext = get_fcontext_nth(I_FIRST); key1 = get_fcontext_key_nth(I_FIRST); key2 = get_fcontext_key_nth(I_SECOND); key3 = get_fcontext_key_nth(I_THIRD); /* test */ CU_ASSERT(semanage_fcontext_compare(fcontext, key1) == 0); CU_ASSERT(semanage_fcontext_compare(fcontext, key2) < 0); CU_ASSERT(semanage_fcontext_compare(fcontext, key3) > 0); /* cleanup */ semanage_fcontext_free(fcontext); semanage_fcontext_key_free(key1); semanage_fcontext_key_free(key2); semanage_fcontext_key_free(key3); cleanup_handle(SH_CONNECT); } /* Function semanage_fcontext_compare2 */ static void test_fcontext_compare2(void) { semanage_fcontext_t *fcontext; semanage_fcontext_t *fcontext1; semanage_fcontext_t *fcontext2; semanage_fcontext_t *fcontext3; /* setup */ setup_handle(SH_CONNECT); fcontext = get_fcontext_nth(I_FIRST); fcontext1 = get_fcontext_nth(I_FIRST); fcontext2 = get_fcontext_nth(I_SECOND); fcontext3 = get_fcontext_nth(I_THIRD); /* test */ CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext1) == 0); CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext2) < 0); CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext3) > 0); /* cleanup */ semanage_fcontext_free(fcontext); semanage_fcontext_free(fcontext1); semanage_fcontext_free(fcontext2); semanage_fcontext_free(fcontext3); cleanup_handle(SH_CONNECT); } /* Function semanage_fcontext_key_create */ static void test_fcontext_key_create(void) { semanage_fcontext_key_t *key = NULL; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_fcontext_key_create(sh, "", SEMANAGE_FCONTEXT_ALL, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); semanage_fcontext_key_free(key); key = NULL; CU_ASSERT(semanage_fcontext_key_create(sh, "testfcontext", SEMANAGE_FCONTEXT_ALL, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); semanage_fcontext_key_free(key); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_fcontext_key_extract */ static void test_fcontext_key_extract(void) { semanage_fcontext_t *fcontext; semanage_fcontext_key_t *key; /* setup */ setup_handle(SH_CONNECT); fcontext = get_fcontext_nth(I_FIRST); /* test */ CU_ASSERT(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* cleanup */ semanage_fcontext_key_free(key); semanage_fcontext_free(fcontext); cleanup_handle(SH_CONNECT); } /* Function semanage_fcontext_get_expr, semanage_fcontext_set_expr */ static void test_fcontext_get_set_expr(void) { semanage_fcontext_t *fcontext; const char *expr = NULL; const char *expr_exp = "/asdf"; /* setup */ setup_handle(SH_CONNECT); fcontext = get_fcontext_nth(I_FIRST); /* test */ CU_ASSERT(semanage_fcontext_set_expr(sh, fcontext, expr_exp) >= 0); expr = semanage_fcontext_get_expr(fcontext); CU_ASSERT_PTR_NOT_NULL(expr); assert(expr); CU_ASSERT_STRING_EQUAL(expr, expr_exp); /* cleanup */ semanage_fcontext_free(fcontext); cleanup_handle(SH_CONNECT); } /* Function semanage_fcontext_get_type, semanage_fcontext_set_type */ static void test_fcontext_get_set_type(void) { semanage_fcontext_t *fcontext; int type_exp = SEMANAGE_FCONTEXT_SOCK; int type; /* setup */ setup_handle(SH_CONNECT); fcontext = get_fcontext_nth(I_FIRST); /* test */ semanage_fcontext_set_type(fcontext, type_exp); type = semanage_fcontext_get_type(fcontext); CU_ASSERT(type == type_exp); /* cleanup */ semanage_fcontext_free(fcontext); cleanup_handle(SH_CONNECT); } /* Function semanage_fcontext_get_type_str */ static void helper_fcontext_get_type_str(int type, const char *exp_str) { CU_ASSERT_STRING_EQUAL(semanage_fcontext_get_type_str(type), exp_str); } static void test_fcontext_get_type_str(void) { helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_ALL, "all files"); helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_REG, "regular file"); helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_DIR, "directory"); helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_CHAR, "character device"); helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_BLOCK, "block device"); helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_SOCK, "socket"); helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_LINK, "symbolic link"); helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_PIPE, "named pipe"); helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_ALL - 1, "????"); helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_PIPE + 1, "????"); } /* Function semanage_fcontext_get_con, semanage_fcontext_set_con */ static void helper_fcontext_get_set_con(level_t level, int fcontext_idx, const char *con_str) { semanage_fcontext_t *fcontext; semanage_context_t *con = NULL; semanage_context_t *new_con = NULL; /* setup */ setup_handle(level); fcontext = get_fcontext_nth(fcontext_idx); if (con_str != NULL) { CU_ASSERT(semanage_context_from_string(sh, con_str, &con) >= 0); CU_ASSERT_PTR_NOT_NULL(con); } else { con = NULL; } /* test */ CU_ASSERT(semanage_fcontext_set_con(sh, fcontext, con) >= 0); new_con = semanage_fcontext_get_con(fcontext); if (con_str != NULL) { CU_ASSERT_CONTEXT_EQUAL(con, new_con); } else { CU_ASSERT_PTR_NULL(new_con); } /* cleanup */ semanage_context_free(con); semanage_fcontext_free(fcontext); cleanup_handle(level); } static void test_fcontext_get_set_con(void) { helper_fcontext_get_set_con(SH_CONNECT, I_FIRST, NULL); helper_fcontext_get_set_con(SH_CONNECT, I_FIRST, "user_u:role_r:type_t:s0"); helper_fcontext_get_set_con(SH_CONNECT, I_SECOND, "user_u:role_r:type_t:s0"); helper_fcontext_get_set_con(SH_TRANS, I_FIRST, NULL); helper_fcontext_get_set_con(SH_TRANS, I_FIRST, "user_u:role_r:type_t:s0"); helper_fcontext_get_set_con(SH_TRANS, I_SECOND, "user_u:role_r:type_t:s0"); } /* Function semanage_fcontext_create */ static void helper_fcontext_create(level_t level) { semanage_fcontext_t *fcontext; /* setup */ setup_handle(level); /* test */ CU_ASSERT(semanage_fcontext_create(sh, &fcontext) >= 0); CU_ASSERT_PTR_NULL(semanage_fcontext_get_expr(fcontext)); CU_ASSERT(semanage_fcontext_get_type(fcontext) == SEMANAGE_FCONTEXT_ALL); CU_ASSERT_PTR_NULL(semanage_fcontext_get_con(fcontext)); /* cleanup */ semanage_fcontext_free(fcontext); cleanup_handle(level); } static void test_fcontext_create(void) { helper_fcontext_create(SH_NULL); helper_fcontext_create(SH_HANDLE); helper_fcontext_create(SH_CONNECT); helper_fcontext_create(SH_TRANS); } /* Function semanage_fcontext_clone */ static void helper_fcontext_clone(level_t level, int fcontext_idx) { semanage_fcontext_t *fcontext; semanage_fcontext_t *fcontext_clone; const char *expr; const char *expr_clone; int type; int type_clone; semanage_context_t *con; semanage_context_t *con_clone; /* setup */ setup_handle(level); fcontext = get_fcontext_nth(fcontext_idx); /* test */ CU_ASSERT(semanage_fcontext_clone(sh, fcontext, &fcontext_clone) >= 0); expr = semanage_fcontext_get_expr(fcontext); expr_clone = semanage_fcontext_get_expr(fcontext_clone); CU_ASSERT_STRING_EQUAL(expr, expr_clone); type = semanage_fcontext_get_type(fcontext); type_clone = semanage_fcontext_get_type(fcontext_clone); CU_ASSERT_EQUAL(type, type_clone); con = semanage_fcontext_get_con(fcontext); con_clone = semanage_fcontext_get_con(fcontext_clone); CU_ASSERT_CONTEXT_EQUAL(con, con_clone); /* cleanup */ semanage_fcontext_free(fcontext); semanage_fcontext_free(fcontext_clone); cleanup_handle(level); } static void test_fcontext_clone(void) { helper_fcontext_clone(SH_CONNECT, I_FIRST); helper_fcontext_clone(SH_CONNECT, I_SECOND); helper_fcontext_clone(SH_TRANS, I_FIRST); helper_fcontext_clone(SH_TRANS, I_SECOND); } /* Function semanage_fcontext_query */ static void helper_fcontext_query(level_t level, const char *fcontext_expr, int fcontext_type, int exp_res) { semanage_fcontext_key_t *key; semanage_fcontext_t *resp = (void *) 42; int res; /* setup */ setup_handle(level); key = get_fcontext_key_from_str(fcontext_expr, fcontext_type); /* test */ res = semanage_fcontext_query(sh, key, &resp); if (exp_res >= 0) { CU_ASSERT(res >= 0); const char *expr = semanage_fcontext_get_expr(resp); CU_ASSERT_STRING_EQUAL(expr, fcontext_expr); semanage_fcontext_free(resp); } else { CU_ASSERT(res < 0); CU_ASSERT(resp == (void *) 42); } /* cleanup */ semanage_fcontext_key_free(key); cleanup_handle(level); } static void test_fcontext_query(void) { helper_fcontext_query(SH_CONNECT, FCONTEXT_NONEXISTENT_EXPR, FCONTEXT_NONEXISTENT_TYPE, -1); helper_fcontext_query(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT1_TYPE, -1); helper_fcontext_query(SH_CONNECT, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1); helper_fcontext_query(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1); helper_fcontext_query(SH_TRANS, FCONTEXT_NONEXISTENT_EXPR, FCONTEXT_NONEXISTENT_TYPE, -1); helper_fcontext_query(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT1_TYPE, -1); helper_fcontext_query(SH_TRANS, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1); helper_fcontext_query(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1); } /* Function semanage_fcontext_exists */ static void helper_fcontext_exists(level_t level, const char *fcontext_expr, int fcontext_type, int exp_resp) { semanage_fcontext_key_t *key; int resp; /* setup */ setup_handle(level); key = get_fcontext_key_from_str(fcontext_expr, fcontext_type); /* test */ CU_ASSERT(semanage_fcontext_exists(sh, key, &resp) >= 0); CU_ASSERT(resp == exp_resp); /* cleanup */ semanage_fcontext_key_free(key); cleanup_handle(level); } static void test_fcontext_exists(void) { helper_fcontext_exists(SH_CONNECT, FCONTEXT_NONEXISTENT_EXPR, FCONTEXT_NONEXISTENT_TYPE, 0); helper_fcontext_exists(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT1_TYPE, 0); helper_fcontext_exists(SH_CONNECT, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1); helper_fcontext_exists(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1); helper_fcontext_exists(SH_TRANS, FCONTEXT_NONEXISTENT_EXPR, FCONTEXT_NONEXISTENT_TYPE, 0); helper_fcontext_exists(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT1_TYPE, 0); helper_fcontext_exists(SH_TRANS, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1); helper_fcontext_exists(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1); } /* Function semanage_fcontext_count */ static void test_fcontext_count(void) { unsigned int resp; /* handle */ setup_handle(SH_HANDLE); CU_ASSERT(semanage_fcontext_count(sh, &resp) < 0); CU_ASSERT(semanage_fcontext_count(sh, NULL) < 0); cleanup_handle(SH_HANDLE); /* connect */ resp = 0; setup_handle(SH_CONNECT); CU_ASSERT(semanage_fcontext_count(sh, &resp) >= 0); CU_ASSERT(resp == FCONTEXTS_COUNT); cleanup_handle(SH_CONNECT); /* trans */ resp = 0; setup_handle(SH_TRANS); CU_ASSERT(semanage_fcontext_count(sh, &resp) >= 0); CU_ASSERT(resp == FCONTEXTS_COUNT); cleanup_handle(SH_TRANS); } /* Function semanage_fcontext_iterate */ static unsigned int counter_fcontext_iterate = 0; static int handler_fcontext_iterate(const semanage_fcontext_t *record, __attribute__((unused)) void *varg) { CU_ASSERT_PTR_NOT_NULL(record); counter_fcontext_iterate++; return 0; } static void helper_fcontext_iterate_invalid(void) { /* setup */ setup_handle(SH_HANDLE); /* test */ CU_ASSERT(semanage_fcontext_iterate(sh, &handler_fcontext_iterate, NULL) < 0); CU_ASSERT(semanage_fcontext_iterate(sh, NULL, NULL) < 0); /* cleanup */ cleanup_handle(SH_HANDLE); } static void helper_fcontext_iterate(level_t level) { /* setup */ setup_handle(level); counter_fcontext_iterate = 0; /* test */ CU_ASSERT(semanage_fcontext_iterate(sh, &handler_fcontext_iterate, NULL) >= 0); CU_ASSERT(counter_fcontext_iterate == FCONTEXTS_COUNT); /* cleanup */ cleanup_handle(level); } static void test_fcontext_iterate(void) { helper_fcontext_iterate_invalid(); helper_fcontext_iterate(SH_CONNECT); helper_fcontext_iterate(SH_TRANS); } /* Function semanage_fcontext_list */ static void helper_fcontext_list_invalid(void) { semanage_fcontext_t **records; unsigned int count; /* setup */ setup_handle(SH_HANDLE); /* test */ CU_ASSERT(semanage_fcontext_list(sh, &records, &count) < 0); CU_ASSERT(semanage_fcontext_list(sh, NULL, &count) < 0); CU_ASSERT(semanage_fcontext_list(sh, &records, NULL) < 0); /* cleanup */ cleanup_handle(SH_HANDLE); } static void helper_fcontext_list(level_t level) { semanage_fcontext_t **records; unsigned int count; /* setup */ setup_handle(level); /* test */ CU_ASSERT(semanage_fcontext_list(sh, &records, &count) >= 0); CU_ASSERT(count == FCONTEXTS_COUNT); for (unsigned int i = 0; i < count; i++) CU_ASSERT_PTR_NOT_NULL(records[i]); for (unsigned int i = 0; i < count; i++) semanage_fcontext_free(records[i]); free(records); /* cleanup */ cleanup_handle(level); } static void test_fcontext_list(void) { helper_fcontext_list_invalid(); helper_fcontext_list(SH_CONNECT); helper_fcontext_list(SH_TRANS); } /* Function semanage_fcontext_modify_local, semanage_fcontext_del_local */ static void helper_fcontext_modify_del_local(level_t level, int fcontext_idx, const char *con_str, int exp_res) { semanage_fcontext_t *fcontext; semanage_fcontext_t *fcontext_local = NULL; semanage_fcontext_key_t *key = NULL; semanage_context_t *con = NULL; int res; /* setup */ setup_handle(level); fcontext = get_fcontext_nth(fcontext_idx); CU_ASSERT(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); if (con_str != NULL) { CU_ASSERT(semanage_context_from_string(sh, con_str, &con) >= 0); CU_ASSERT_PTR_NOT_NULL(con); } else { con = NULL; } CU_ASSERT(semanage_fcontext_set_con(sh, fcontext, con) >= 0); /* test */ res = semanage_fcontext_modify_local(sh, key, fcontext); if (exp_res >= 0) { CU_ASSERT(res >= 0); if (level == SH_TRANS) { helper_commit(); helper_begin_transaction(); } CU_ASSERT(semanage_fcontext_query_local(sh, key, &fcontext_local) >= 0); CU_ASSERT(semanage_fcontext_compare2(fcontext_local, fcontext) == 0); semanage_fcontext_free(fcontext_local); CU_ASSERT(semanage_fcontext_del_local(sh, key) >= 0); CU_ASSERT(semanage_fcontext_query_local(sh, key, &fcontext_local) < 0); } else { CU_ASSERT(res < 0); } /* cleanup */ semanage_context_free(con); semanage_fcontext_key_free(key); semanage_fcontext_free(fcontext); cleanup_handle(level); } static void test_fcontext_modify_del_local(void) { helper_fcontext_modify_del_local(SH_CONNECT, I_FIRST, "system_u:object_r:tmp_t:s0", -1); helper_fcontext_modify_del_local(SH_CONNECT, I_SECOND, "system_u:object_r:tmp_t:s0", -1); helper_fcontext_modify_del_local(SH_TRANS, I_FIRST, "system_u:object_r:tmp_t:s0", 1); helper_fcontext_modify_del_local(SH_TRANS, I_SECOND, "system_u:object_r:tmp_t:s0", 1); } /* Function semanage_fcontext_query_local */ static void test_fcontext_query_local(void) { semanage_fcontext_key_t *key = NULL; semanage_fcontext_t *resp = NULL; /* connect */ setup_handle(SH_CONNECT); key = get_fcontext_key_nth(I_FIRST); CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) < 0); CU_ASSERT_PTR_NULL(resp); cleanup_handle(SH_CONNECT); /* transaction */ setup_handle(SH_TRANS); semanage_fcontext_key_free(key); key = get_fcontext_key_nth(I_FIRST); CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) < 0); CU_ASSERT_PTR_NULL(resp); add_local_fcontext(I_FIRST); CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) >= 0); CU_ASSERT_PTR_NOT_NULL(resp); semanage_fcontext_free(resp); resp = NULL; semanage_fcontext_key_free(key); key = get_fcontext_key_nth(I_SECOND); add_local_fcontext(I_SECOND); CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) >= 0); CU_ASSERT_PTR_NOT_NULL(resp); semanage_fcontext_free(resp); resp = NULL; /* cleanup */ semanage_fcontext_key_free(key); delete_local_fcontext(I_FIRST); delete_local_fcontext(I_SECOND); cleanup_handle(SH_TRANS); } /* Function semanage_fcontext_exists_local */ static void test_fcontext_exists_local(void) { int resp = -1; semanage_fcontext_key_t *key; /* setup */ setup_handle(SH_TRANS); key = get_fcontext_key_nth(I_FIRST); /* test */ CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0); CU_ASSERT(resp == 0); add_local_fcontext(I_FIRST); resp = -1; CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0); CU_ASSERT(resp == 1); delete_local_fcontext(I_FIRST); resp = -1; CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0); CU_ASSERT(resp == 0); resp = -1; CU_ASSERT(semanage_fcontext_exists_local(sh, NULL, &resp) >= 0); CU_ASSERT(resp == 0); /* cleanup */ semanage_fcontext_key_free(key); cleanup_handle(SH_TRANS); } /* Function semanage_fcontext_count_local */ static void test_fcontext_count_local(void) { unsigned int resp; /* handle */ setup_handle(SH_HANDLE); CU_ASSERT(semanage_fcontext_count_local(sh, &resp) < 0); cleanup_handle(SH_HANDLE); /* connect */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0); CU_ASSERT(resp == 0); cleanup_handle(SH_CONNECT); /* transaction */ setup_handle(SH_TRANS); CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0); CU_ASSERT(resp == 0); add_local_fcontext(I_FIRST); CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0); CU_ASSERT(resp == 1); add_local_fcontext(I_SECOND); CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0); CU_ASSERT(resp == 2); delete_local_fcontext(I_SECOND); CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0); CU_ASSERT(resp == 1); /* cleanup */ delete_local_fcontext(I_FIRST); cleanup_handle(SH_TRANS); } /* Function semanage_fcontext_iterate_local */ static unsigned int counter_fcontext_iterate_local = 0; static int handler_fcontext_iterate_local(const semanage_fcontext_t *record, __attribute__((unused)) void *varg) { CU_ASSERT_PTR_NOT_NULL(record); counter_fcontext_iterate_local++; return 0; } static void test_fcontext_iterate_local(void) { /* handle */ setup_handle(SH_HANDLE); CU_ASSERT(semanage_fcontext_iterate_local(sh, &handler_fcontext_iterate_local, NULL) < 0); CU_ASSERT(semanage_fcontext_iterate_local(sh, NULL, NULL) < 0); cleanup_handle(SH_HANDLE); /* connect */ setup_handle(SH_CONNECT); counter_fcontext_iterate_local = 0; CU_ASSERT(semanage_fcontext_iterate_local(sh, &handler_fcontext_iterate_local, NULL) >= 0); CU_ASSERT(counter_fcontext_iterate_local == 0); CU_ASSERT(semanage_fcontext_iterate_local(sh, NULL, NULL) >= 0); cleanup_handle(SH_CONNECT); /* transaction */ setup_handle(SH_TRANS); counter_fcontext_iterate_local = 0; CU_ASSERT(semanage_fcontext_iterate_local(sh, &handler_fcontext_iterate_local, NULL) >= 0); CU_ASSERT(counter_fcontext_iterate_local == 0); add_local_fcontext(I_FIRST); counter_fcontext_iterate_local = 0; CU_ASSERT(semanage_fcontext_iterate_local(sh, &handler_fcontext_iterate_local, NULL) >= 0); CU_ASSERT(counter_fcontext_iterate_local == 1); add_local_fcontext(I_SECOND); counter_fcontext_iterate_local = 0; CU_ASSERT(semanage_fcontext_iterate_local(sh, &handler_fcontext_iterate_local, NULL) >= 0); CU_ASSERT(counter_fcontext_iterate_local == 2); /* cleanup */ delete_local_fcontext(I_FIRST); delete_local_fcontext(I_SECOND); cleanup_handle(SH_TRANS); } /* Function semanage_fcontext_list_local */ static void test_fcontext_list_local(void) { semanage_fcontext_t **records; unsigned int count; /* handle */ setup_handle(SH_HANDLE); CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) < 0); CU_ASSERT(semanage_fcontext_list_local(sh, NULL, &count) < 0); CU_ASSERT(semanage_fcontext_list_local(sh, &records, NULL) < 0); cleanup_handle(SH_HANDLE); /* connect */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0); CU_ASSERT(count == 0); cleanup_handle(SH_CONNECT); /* transaction */ setup_handle(SH_TRANS); CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0); CU_ASSERT(count == 0); add_local_fcontext(I_FIRST); CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0); CU_ASSERT(count == 1); CU_ASSERT_PTR_NOT_NULL(records[0]); semanage_fcontext_free(records[0]); free(records); add_local_fcontext(I_SECOND); CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0); CU_ASSERT(count == 2); CU_ASSERT_PTR_NOT_NULL(records[0]); CU_ASSERT_PTR_NOT_NULL(records[1]); semanage_fcontext_free(records[0]); semanage_fcontext_free(records[1]); free(records); /* cleanup */ delete_local_fcontext(I_FIRST); delete_local_fcontext(I_SECOND); cleanup_handle(SH_TRANS); } libsemanage-3.8.1/tests/test_fcontext.cil000066400000000000000000000012101476211737200205220ustar00rootroot00000000000000(typeattribute cil_gen_require) (roleattribute cil_gen_require) (handleunknown allow) (mls true) (policycap network_peer_controls) (policycap open_perms) (sid security) (sidorder (security)) (sensitivity s0) (sensitivityorder (s0)) (user system_u) (userrole system_u object_r) (userlevel system_u (s0)) (userrange system_u ((s0) (s0))) (role object_r) (roletype object_r first_t) (roletype object_r second_t) (roletype object_r third_t) (type first_t) (type second_t) (type third_t) (sidcontext security (system_u object_r first_t ((s0) (s0)))) (class test_class (test_perm)) (classorder (test_class)) (allow first_t self (test_class (test_perm))) libsemanage-3.8.1/tests/test_fcontext.h000066400000000000000000000020021476211737200202020ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 __TEST_FCONTEXT_H__ #define __TEST_FCONTEXT_H__ #include int fcontext_test_init(void); int fcontext_test_cleanup(void); int fcontext_add_tests(CU_pSuite suite); #endif libsemanage-3.8.1/tests/test_handle.c000066400000000000000000000176511476211737200176160ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 "utilities.h" #include "test_handle.h" static void test_handle_create(void); static void test_connect(void); static void test_disconnect(void); static void test_transaction(void); static void test_commit(void); static void test_is_connected(void); static void test_access_check(void); static void test_is_managed(void); static void test_mls_enabled(void); static void test_msg_set_callback(void); static void test_root(void); static void test_select_store(void); int handle_test_init(void) { if (create_test_store() < 0) { fprintf(stderr, "Could not create test store\n"); return 1; } if (write_test_policy_from_file("test_handle.policy") < 0) { fprintf(stderr, "Could not write test policy\n"); return 1; } return 0; } int handle_test_cleanup(void) { if (destroy_test_store() < 0) { fprintf(stderr, "Could not destroy test store\n"); return 1; } return 0; } int handle_add_tests(CU_pSuite suite) { CU_add_test(suite, "test_handle_create", test_handle_create); CU_add_test(suite, "test_connect", test_connect); CU_add_test(suite, "test_disconnect", test_disconnect); CU_add_test(suite, "test_transaction", test_transaction); CU_add_test(suite, "test_commit", test_commit); CU_add_test(suite, "test_is_connected", test_is_connected); CU_add_test(suite, "test_access_check", test_access_check); CU_add_test(suite, "test_is_managed", test_is_managed); CU_add_test(suite, "test_mls_enabled", test_mls_enabled); CU_add_test(suite, "msg_set_callback", test_msg_set_callback); CU_add_test(suite, "test_root", test_root); CU_add_test(suite, "test_select_store", test_select_store); return 0; } /* Function semanage_handle_create */ static void test_handle_create(void) { sh = semanage_handle_create(); CU_ASSERT_PTR_NOT_NULL(sh); semanage_handle_destroy(sh); } /* Function semanage_connect */ static void test_connect(void) { /* test handle created */ setup_handle(SH_HANDLE); CU_ASSERT(semanage_connect(sh) >= 0); CU_ASSERT(semanage_disconnect(sh) >= 0); cleanup_handle(SH_HANDLE); /* test invalid store */ setup_handle_invalid_store(SH_HANDLE); CU_ASSERT(semanage_connect(sh) < 0); cleanup_handle(SH_HANDLE); /* test normal use */ setup_handle(SH_HANDLE); CU_ASSERT(semanage_connect(sh) >= 0); CU_ASSERT(semanage_disconnect(sh) >= 0); cleanup_handle(SH_HANDLE); } /* Function semanage_disconnect */ static void test_disconnect(void) { setup_handle(SH_CONNECT); CU_ASSERT(semanage_disconnect(sh) >= 0); cleanup_handle(SH_HANDLE); } /* Function semanage_begin_transaction */ static void test_transaction(void) { /* test disconnected */ setup_handle(SH_CONNECT); helper_disconnect(); CU_ASSERT(semanage_begin_transaction(sh) < 0); cleanup_handle(SH_HANDLE); /* test normal use */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_begin_transaction(sh) >= 0); CU_ASSERT(semanage_commit(sh) >= 0); cleanup_handle(SH_CONNECT); } /* Function semanage_commit */ static void test_commit(void) { /* test without transaction */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_commit(sh) < 0); /* test with transaction */ helper_begin_transaction(); CU_ASSERT(semanage_commit(sh) >= 0); cleanup_handle(SH_CONNECT); } /* Function semanage_is_connected */ static void test_is_connected(void) { /* test disconnected */ setup_handle(SH_HANDLE); CU_ASSERT(semanage_is_connected(sh) == 0); /* test connected */ helper_connect(); CU_ASSERT(semanage_is_connected(sh) == 1); /* test in transaction */ helper_begin_transaction(); CU_ASSERT(semanage_is_connected(sh) == 1); cleanup_handle(SH_TRANS); } /* Function semanage_access_check */ static void test_access_check(void) { int res = 0; /* test with handle */ setup_handle(SH_HANDLE); res = semanage_access_check(sh); CU_ASSERT(res == 0 || res == SEMANAGE_CAN_READ || res == SEMANAGE_CAN_WRITE); cleanup_handle(SH_HANDLE); /* test with invalid store */ setup_handle_invalid_store(SH_HANDLE); CU_ASSERT(semanage_access_check(sh) < 0); cleanup_handle(SH_HANDLE); /* test connected */ setup_handle(SH_CONNECT); res = semanage_access_check(sh); CU_ASSERT(res == 0 || res == SEMANAGE_CAN_READ || res == SEMANAGE_CAN_WRITE); cleanup_handle(SH_CONNECT); } /* Function semanage_is_managed */ static void test_is_managed(void) { int res = 0; /* test with handle */ setup_handle(SH_HANDLE); res = semanage_is_managed(sh); CU_ASSERT(res == 0 || res == 1); /* test connected */ helper_connect(); res = semanage_is_managed(sh); CU_ASSERT(res < 0); cleanup_handle(SH_CONNECT); } /* Function semanage_mls_enabled */ static void test_mls_enabled(void) { int res = 0; /* test with handle */ setup_handle(SH_HANDLE); res = semanage_mls_enabled(sh); CU_ASSERT(res == 0 || res == 1); cleanup_handle(SH_HANDLE); /* test with invalid store */ setup_handle_invalid_store(SH_HANDLE); CU_ASSERT(semanage_mls_enabled(sh) < 0); cleanup_handle(SH_HANDLE); /* test connected */ setup_handle(SH_CONNECT); res = semanage_mls_enabled(sh); CU_ASSERT(res == 0 || res == 1); cleanup_handle(SH_CONNECT); } /* Function semanage_set_callback */ static int msg_set_callback_count = 0; static void helper_msg_set_callback(__attribute__((unused)) void *varg, __attribute__((unused)) semanage_handle_t *handle, __attribute__((unused)) const char *fmt, ...) { msg_set_callback_count++; } static void test_msg_set_callback(void) { setup_handle(SH_CONNECT); semanage_msg_set_callback(sh, helper_msg_set_callback, NULL); /* produce error message */ semanage_commit(sh); CU_ASSERT(msg_set_callback_count == 1); semanage_msg_set_callback(sh, NULL, NULL); /* produce error message */ semanage_commit(sh); CU_ASSERT(msg_set_callback_count == 1); cleanup_handle(SH_CONNECT); } /* Function semanage_root, semanage_set_root */ static void helper_root(void) { const char *root = NULL; CU_ASSERT(semanage_set_root("asdf") >= 0); root = semanage_root(); CU_ASSERT_STRING_EQUAL(root, "asdf"); CU_ASSERT(semanage_set_root("") >= 0); root = semanage_root(); CU_ASSERT_STRING_EQUAL(root, ""); } static void test_root(void) { /* test without handle */ setup_handle(SH_NULL); helper_root(); /* test with handle */ helper_handle_create(); helper_root(); /* test connected */ helper_connect(); helper_root(); cleanup_handle(SH_CONNECT); } /* Function semanage_select_store */ static void helper_select_store(const char *name, enum semanage_connect_type type, int exp_res) { setup_handle(SH_HANDLE); /* FIXME: the storename parameter of semanage_select_store should be * 'const char *' */ semanage_select_store(sh, name, type); int res = semanage_connect(sh); if (exp_res < 0) { CU_ASSERT(res < 0); } else { CU_ASSERT(res >= 0); } if (res >= 0) cleanup_handle(SH_CONNECT); else cleanup_handle(SH_HANDLE); } static void test_select_store(void) { helper_select_store("asdf", SEMANAGE_CON_INVALID - 1, -1); helper_select_store("asdf", SEMANAGE_CON_POLSERV_REMOTE + 1, -1); helper_select_store("", SEMANAGE_CON_DIRECT, 0); helper_select_store("asdf", SEMANAGE_CON_INVALID, -1); helper_select_store("asdf", SEMANAGE_CON_DIRECT, 0); helper_select_store("asdf", SEMANAGE_CON_POLSERV_LOCAL, -1); helper_select_store("asdf", SEMANAGE_CON_POLSERV_REMOTE, -1); } libsemanage-3.8.1/tests/test_handle.cil000066400000000000000000000010541476211737200201310ustar00rootroot00000000000000(typeattribute cil_gen_require) (roleattribute cil_gen_require) (handleunknown allow) (mls true) (policycap network_peer_controls) (policycap open_perms) (sid security) (sidorder (security)) (sensitivity s0) (sensitivityorder (s0)) (user system_u) (userrole system_u object_r) (userlevel system_u (s0)) (userrange system_u ((s0) (s0))) (role object_r) (roletype object_r test_t) (type test_t) (sidcontext security (system_u object_r test_t ((s0) (s0)))) (class test_class (test_perm)) (classorder (test_class)) (allow test_t self (test_class (test_perm))) libsemanage-3.8.1/tests/test_handle.h000066400000000000000000000017701476211737200176160ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 __TEST_HANDLE_H__ #define __TEST_HANDLE_H__ #include int handle_test_init(void); int handle_test_cleanup(void); int handle_add_tests(CU_pSuite suite); #endif libsemanage-3.8.1/tests/test_ibendport.c000066400000000000000000000344321476211737200203450ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 "utilities.h" #include "test_ibendport.h" #define IBENDPORT_COUNT 3 #define IBENDPORT_1_NAME "mlx4_0" #define IBENDPORT_1_PORT 1 #define IBENDPORT_1_CON "system_u:object_r:first_ibendport_t:s0" #define IBENDPORT_2_NAME "mlx4_1" #define IBENDPORT_2_PORT 2 #define IBENDPORT_2_CON "system_u:object_r:second_ibendport_second_t:s0" #define IBENDPORT_3_NAME "mlx4_1" #define IBENDPORT_3_PORT 3 #define IBENDPORT_3_CON "system_u:object_r:third_ibendport_second_t:s0" /* ibendports_policy.h */ static void test_ibendport_query(void); static void test_ibendport_exists(void); static void test_ibendport_count(void); static void test_ibendport_iterate(void); static void test_ibendport_list(void); /* ibendports_local.h */ static void test_ibendport_modify_del_query_local(void); static void test_ibendport_exists_local(void); static void test_ibendport_count_local(void); static void test_ibendport_iterate_local(void); static void test_ibendport_list_local(void); int ibendport_test_init(void) { if (create_test_store() < 0) { fprintf(stderr, "Could not create test store\n"); return 1; } if (write_test_policy_from_file("test_ibendport.policy") < 0) { fprintf(stderr, "Could not write test policy\n"); return 1; } return 0; } int ibendport_test_cleanup(void) { if (destroy_test_store() < 0) { fprintf(stderr, "Could not destroy test store\n"); return 1; } return 0; } int ibendport_add_tests(CU_pSuite suite) { CU_add_test(suite, "ibendport_query", test_ibendport_query); CU_add_test(suite, "ibendport_exists", test_ibendport_exists); CU_add_test(suite, "ibendport_count", test_ibendport_count); CU_add_test(suite, "ibendport_iterate", test_ibendport_iterate); CU_add_test(suite, "ibendport_list", test_ibendport_list); CU_add_test(suite, "ibendport_modify_del_query_local", test_ibendport_modify_del_query_local); CU_add_test(suite, "ibendport_exists_local", test_ibendport_exists_local); CU_add_test(suite, "ibendport_count_local", test_ibendport_count_local); CU_add_test(suite, "ibendport_iterate_local", test_ibendport_iterate_local); CU_add_test(suite, "ibendport_list_local", test_ibendport_list_local); return 0; } /* Helpers */ static semanage_ibendport_t *get_ibendport_nth(int idx) { semanage_ibendport_t **records; semanage_ibendport_t *ibendport; unsigned int count; if (idx == I_NULL) return NULL; CU_ASSERT_FATAL(semanage_ibendport_list(sh, &records, &count) >= 0); CU_ASSERT_FATAL(count >= (unsigned int) idx + 1); ibendport = records[idx]; for (unsigned int i = 0; i < count; i++) if (i != (unsigned int) idx) semanage_ibendport_free(records[i]); free(records); return ibendport; } static semanage_ibendport_key_t *get_ibendport_key_nth(int idx) { semanage_ibendport_key_t *key; semanage_ibendport_t *ibendport; int res; if (idx == I_NULL) return NULL; ibendport = get_ibendport_nth(idx); res = semanage_ibendport_key_extract(sh, ibendport, &key); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); semanage_ibendport_free(ibendport); return key; } static void add_local_ibendport(int idx) { semanage_ibendport_t *ibendport; semanage_ibendport_key_t *key = NULL; ibendport = get_ibendport_nth(idx); CU_ASSERT_FATAL(semanage_ibendport_key_extract(sh, ibendport, &key) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); CU_ASSERT_FATAL(semanage_ibendport_modify_local(sh, key, ibendport) >= 0); semanage_ibendport_key_free(key); semanage_ibendport_free(ibendport); } static void delete_local_ibendport(int idx) { semanage_ibendport_key_t *key = NULL; key = get_ibendport_key_nth(idx); CU_ASSERT_FATAL(semanage_ibendport_del_local(sh, key) >= 0); semanage_ibendport_key_free(key); } /* Function semanage_ibendport_query */ static void test_ibendport_query(void) { semanage_ibendport_t *ibendport = NULL; semanage_ibendport_t *ibendport_exp = NULL; semanage_ibendport_key_t *key = NULL; semanage_context_t *con = NULL; semanage_context_t *con_exp = NULL; char *name; char *name_exp; /* setup */ setup_handle(SH_CONNECT); key = get_ibendport_key_nth(I_FIRST); ibendport_exp = get_ibendport_nth(I_FIRST); /* test */ CU_ASSERT(semanage_ibendport_query(sh, key, &ibendport) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(ibendport); CU_ASSERT(semanage_ibendport_get_ibdev_name(sh, ibendport, &name) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(name); CU_ASSERT(semanage_ibendport_get_ibdev_name(sh, ibendport_exp, &name_exp) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(name_exp); assert(name); CU_ASSERT_STRING_EQUAL(name, name_exp); CU_ASSERT(semanage_ibendport_get_port(ibendport) == semanage_ibendport_get_port(ibendport_exp)); con = semanage_ibendport_get_con(ibendport); con_exp = semanage_ibendport_get_con(ibendport_exp); CU_ASSERT_PTR_NOT_NULL_FATAL(con); CU_ASSERT_PTR_NOT_NULL_FATAL(con_exp); CU_ASSERT_CONTEXT_EQUAL(con, con_exp); /* cleanup */ free(name_exp); free(name); semanage_ibendport_key_free(key); semanage_ibendport_free(ibendport); semanage_ibendport_free(ibendport_exp); cleanup_handle(SH_CONNECT); } /* Function semanage_ibendport_exists */ static void test_ibendport_exists(void) { semanage_ibendport_key_t *key1 = NULL; semanage_ibendport_key_t *key2 = NULL; int resp = 42; /* setup */ setup_handle(SH_CONNECT); key1 = get_ibendport_key_nth(I_FIRST); CU_ASSERT(semanage_ibendport_key_create(sh, "asdf", 1, &key2) >= 0); /* test */ CU_ASSERT(semanage_ibendport_exists(sh, key1, &resp) >= 0); CU_ASSERT(resp); CU_ASSERT(semanage_ibendport_exists(sh, key2, &resp) >= 0); CU_ASSERT(!resp); /* cleanup */ semanage_ibendport_key_free(key1); semanage_ibendport_key_free(key2); cleanup_handle(SH_CONNECT); } /* Function semanage_ibendport_count */ static void test_ibendport_count(void) { unsigned int count = 42; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_ibendport_count(sh, &count) >= 0); CU_ASSERT(count == IBENDPORT_COUNT); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_ibendport_iterate */ static unsigned int helper_ibendport_iterate_counter = 0; static int helper_ibendport_iterate(__attribute__((unused)) const semanage_ibendport_t *ibendport, void *fn_arg) { CU_ASSERT(fn_arg == (void *) 42); helper_ibendport_iterate_counter++; return 0; } static int helper_ibendport_iterate_error(__attribute__((unused)) const semanage_ibendport_t *ibendport, void *fn_arg) { CU_ASSERT(fn_arg == (void *) 42); helper_ibendport_iterate_counter++; return -1; } static int helper_ibendport_iterate_break(__attribute__((unused)) const semanage_ibendport_t *ibendport, void *fn_arg) { CU_ASSERT(fn_arg == (void *) 42); helper_ibendport_iterate_counter++; return 1; } static void test_ibendport_iterate(void) { /* setup */ setup_handle(SH_CONNECT); /* test */ helper_ibendport_iterate_counter = 0; CU_ASSERT(semanage_ibendport_iterate(sh, helper_ibendport_iterate, (void *) 42) >= 0); CU_ASSERT(helper_ibendport_iterate_counter == IBENDPORT_COUNT); /* test function which returns error */ helper_ibendport_iterate_counter = 0; CU_ASSERT(semanage_ibendport_iterate(sh, helper_ibendport_iterate_error, (void *) 42) < 0); CU_ASSERT(helper_ibendport_iterate_counter == 1); /* test function which requests break */ helper_ibendport_iterate_counter = 0; CU_ASSERT(semanage_ibendport_iterate(sh, helper_ibendport_iterate_break, (void *) 42) >= 0); CU_ASSERT(helper_ibendport_iterate_counter == 1); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_ibendport_list */ static void test_ibendport_list(void) { semanage_ibendport_t **records = NULL; unsigned int count = 42; char *name = NULL; semanage_context_t *con = NULL; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_ibendport_list(sh, &records, &count) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(records); assert(records); CU_ASSERT(count == IBENDPORT_COUNT); for (unsigned int i = 0; i < count; i++) { CU_ASSERT_PTR_NOT_NULL_FATAL(records[i]); CU_ASSERT(semanage_ibendport_get_ibdev_name(sh, records[i], &name) >= 0); con = semanage_ibendport_get_con(records[i]); CU_ASSERT_PTR_NOT_NULL_FATAL(con); free(name); } /* cleanup */ for (unsigned int i = 0; i < count; i++) semanage_ibendport_free(records[i]); free(records); cleanup_handle(SH_CONNECT); } /* Function semanage_ibendport_modify_local, semanage_ibendport_del_local, * semanage_ibendport_query_local */ static void test_ibendport_modify_del_query_local(void) { semanage_ibendport_t *ibendport; semanage_ibendport_t *ibendport_local; semanage_ibendport_key_t *key = NULL; /* setup */ setup_handle(SH_TRANS); ibendport = get_ibendport_nth(I_FIRST); CU_ASSERT(semanage_ibendport_key_extract(sh, ibendport, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* test */ CU_ASSERT(semanage_ibendport_modify_local(sh, key, ibendport) >= 0); /* write changes to file */ helper_commit(); helper_begin_transaction(); CU_ASSERT(semanage_ibendport_query_local(sh, key, &ibendport_local) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(ibendport_local); semanage_ibendport_free(ibendport_local); CU_ASSERT(semanage_ibendport_del_local(sh, key) >= 0); CU_ASSERT(semanage_ibendport_query_local(sh, key, &ibendport_local) < 0); /* cleanup */ semanage_ibendport_key_free(key); semanage_ibendport_free(ibendport); cleanup_handle(SH_TRANS); } /* Function semanage_ibendport_exists_local */ static void test_ibendport_exists_local(void) { semanage_ibendport_key_t *key1 = NULL; semanage_ibendport_key_t *key2 = NULL; int resp = 42; /* setup */ setup_handle(SH_TRANS); add_local_ibendport(I_FIRST); key1 = get_ibendport_key_nth(I_FIRST); key2 = get_ibendport_key_nth(I_SECOND); /* test */ CU_ASSERT(semanage_ibendport_exists_local(sh, key1, &resp) >= 0); CU_ASSERT(resp); CU_ASSERT(semanage_ibendport_exists_local(sh, key2, &resp) >= 0); CU_ASSERT(!resp); /* cleanup */ CU_ASSERT(semanage_ibendport_del_local(sh, key1) >= 0); semanage_ibendport_key_free(key1); semanage_ibendport_key_free(key2); cleanup_handle(SH_TRANS); } /* Function semanage_ibendport_count_local */ static void test_ibendport_count_local(void) { unsigned int count = 42; /* setup */ setup_handle(SH_TRANS); /* test */ CU_ASSERT(semanage_ibendport_count_local(sh, &count) >= 0); CU_ASSERT(count == 0); add_local_ibendport(I_FIRST); CU_ASSERT(semanage_ibendport_count_local(sh, &count) >= 0); CU_ASSERT(count == 1); add_local_ibendport(I_SECOND); CU_ASSERT(semanage_ibendport_count_local(sh, &count) >= 0); CU_ASSERT(count == 2); delete_local_ibendport(I_SECOND); CU_ASSERT(semanage_ibendport_count_local(sh, &count) >= 0); CU_ASSERT(count == 1); delete_local_ibendport(I_FIRST); CU_ASSERT(semanage_ibendport_count_local(sh, &count) >= 0); CU_ASSERT(count == 0); /* cleanup */ cleanup_handle(SH_TRANS); } /* Function semanage_ibendport_iterate_local */ static unsigned int helper_ibendport_iterate_local_counter = 0; static int helper_ibendport_iterate_local(__attribute__((unused)) const semanage_ibendport_t *ibendport, void *fn_arg) { CU_ASSERT(fn_arg == (void *) 42); helper_ibendport_iterate_local_counter++; return 0; } static int helper_ibendport_iterate_local_error(__attribute__((unused)) const semanage_ibendport_t *ibendport, void *fn_arg) { CU_ASSERT(fn_arg == (void *) 42); helper_ibendport_iterate_local_counter++; return -1; } static int helper_ibendport_iterate_local_break(__attribute__((unused)) const semanage_ibendport_t *ibendport, void *fn_arg) { CU_ASSERT(fn_arg == (void *) 42); helper_ibendport_iterate_local_counter++; return 1; } static void test_ibendport_iterate_local(void) { /* setup */ setup_handle(SH_TRANS); add_local_ibendport(I_FIRST); add_local_ibendport(I_SECOND); add_local_ibendport(I_THIRD); /* test */ helper_ibendport_iterate_local_counter = 0; CU_ASSERT(semanage_ibendport_iterate_local(sh, helper_ibendport_iterate_local, (void *) 42) >= 0); CU_ASSERT(helper_ibendport_iterate_local_counter == 3); /* test function which returns error */ helper_ibendport_iterate_local_counter = 0; CU_ASSERT(semanage_ibendport_iterate_local(sh, helper_ibendport_iterate_local_error, (void *) 42) < 0); CU_ASSERT(helper_ibendport_iterate_local_counter == 1); /* test function which requests break */ helper_ibendport_iterate_local_counter = 0; CU_ASSERT(semanage_ibendport_iterate_local(sh, helper_ibendport_iterate_local_break, (void *) 42) >= 0); /* cleanup */ delete_local_ibendport(I_FIRST); delete_local_ibendport(I_SECOND); delete_local_ibendport(I_THIRD); cleanup_handle(SH_TRANS); } /* Function semanage_ibendport_list_local */ static void test_ibendport_list_local(void) { semanage_ibendport_t **records = NULL; unsigned int count = 42; char *name = NULL; semanage_context_t *con = NULL; /* setup */ setup_handle(SH_TRANS); add_local_ibendport(I_FIRST); add_local_ibendport(I_SECOND); add_local_ibendport(I_THIRD); /* test */ CU_ASSERT(semanage_ibendport_list_local(sh, &records, &count) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(records); assert(records); CU_ASSERT(count == 3); for (unsigned int i = 0; i < count; i++) { CU_ASSERT_PTR_NOT_NULL_FATAL(records[i]); CU_ASSERT(semanage_ibendport_get_ibdev_name(sh, records[i], &name) >= 0); con = semanage_ibendport_get_con(records[i]); CU_ASSERT_PTR_NOT_NULL_FATAL(con); free(name); } /* cleanup */ for (unsigned int i = 0; i < count; i++) semanage_ibendport_free(records[i]); free(records); delete_local_ibendport(I_FIRST); delete_local_ibendport(I_SECOND); delete_local_ibendport(I_THIRD); cleanup_handle(SH_TRANS); } libsemanage-3.8.1/tests/test_ibendport.cil000066400000000000000000000016671476211737200206760ustar00rootroot00000000000000(typeattribute cil_gen_require) (roleattribute cil_gen_require) (handleunknown allow) (mls true) (policycap network_peer_controls) (policycap open_perms) (sid security) (sidorder (security)) (sensitivity s0) (sensitivityorder (s0)) (user system_u) (userrole system_u object_r) (userlevel system_u (s0)) (userrange system_u ((s0) (s0))) (role object_r) (roletype object_r first_ibendport_t) (roletype object_r second_ibendport_t) (roletype object_r third_ibendport_t) (type first_ibendport_t) (type second_ibendport_t) (type third_ibendport_t) (sidcontext security (system_u object_r first_ibendport_t ((s0) (s0)))) (class test_class (test_perm)) (classorder (test_class)) (allow first_ibendport_t self (test_class (test_perm))) (ibendportcon mlx4_0 1 (system_u object_r first_ibendport_t ((s0) (s0)))) (ibendportcon mlx4_1 2 (system_u object_r second_ibendport_t ((s0) (s0)))) (ibendportcon mlx4_1 3 (system_u object_r third_ibendport_t ((s0) (s0)))) libsemanage-3.8.1/tests/test_ibendport.h000066400000000000000000000020071476211737200203430ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 __TEST_IBENDPORT_H__ #define __TEST_IBENDPORT_H__ #include int ibendport_test_init(void); int ibendport_test_cleanup(void); int ibendport_add_tests(CU_pSuite suite); #endif libsemanage-3.8.1/tests/test_iface.c000066400000000000000000000424361476211737200174310ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 "utilities.h" #include "test_iface.h" #define IFACE_COUNT 3 #define IFACE1_NAME "eth0" #define IFACE1_IFCON "system_u:object_r:first_netif_t:s0" #define IFACE1_MSGCON IFACE1_IFCON #define IFACE2_NAME "eth1" #define IFACE2_IFCON "system_u:object_r:second_netif_t:s0" #define IFACE2_MSGCON IFACE2_IFCON #define IFACE3_NAME "eth2" #define IFACE3_IFCON "system_u:object_r:third_netif_t:s0" #define IFACE3_MSGCON IFACE3_IFCON /* iface_record.h */ static void test_iface_compare(void); static void test_iface_compare2(void); static void test_iface_key_create(void); static void test_iface_key_extract(void); static void test_iface_get_set_name(void); static void test_iface_get_set_ifcon(void); static void test_iface_get_set_msgcon(void); static void test_iface_create(void); static void test_iface_clone(void); /* interfaces_policy.h */ static void test_iface_query(void); static void test_iface_exists(void); static void test_iface_count(void); static void test_iface_iterate(void); static void test_iface_list(void); /* interfaces_local.h */ static void test_iface_modify_del_query_local(void); static void test_iface_exists_local(void); static void test_iface_count_local(void); static void test_iface_iterate_local(void); static void test_iface_list_local(void); int iface_test_init(void) { if (create_test_store() < 0) { fprintf(stderr, "Could not create test store\n"); return 1; } if (write_test_policy_from_file("test_iface.policy") < 0) { fprintf(stderr, "Could not write test policy\n"); return 1; } return 0; } int iface_test_cleanup(void) { if (destroy_test_store() < 0) { fprintf(stderr, "Could not destroy test store\n"); return 1; } return 0; } int iface_add_tests(CU_pSuite suite) { CU_add_test(suite, "iface_compare", test_iface_compare); CU_add_test(suite, "iface_compare2", test_iface_compare2); CU_add_test(suite, "iface_key_create", test_iface_key_create); CU_add_test(suite, "iface_key_extract", test_iface_key_extract); CU_add_test(suite, "iface_get_set_name", test_iface_get_set_name); CU_add_test(suite, "iface_get_set_ifcon", test_iface_get_set_ifcon); CU_add_test(suite, "iface_get_set_msgcon", test_iface_get_set_msgcon); CU_add_test(suite, "iface_create)", test_iface_create); CU_add_test(suite, "iface_clone);", test_iface_clone); CU_add_test(suite, "iface_query", test_iface_query); CU_add_test(suite, "iface_exists", test_iface_exists); CU_add_test(suite, "iface_count", test_iface_count); CU_add_test(suite, "iface_iterate", test_iface_iterate); CU_add_test(suite, "iface_list", test_iface_list); CU_add_test(suite, "iface_modify_del_query_local", test_iface_modify_del_query_local); CU_add_test(suite, "iface_exists_local", test_iface_exists_local); CU_add_test(suite, "iface_count_local", test_iface_count_local); CU_add_test(suite, "iface_iterate_local", test_iface_iterate_local); CU_add_test(suite, "iface_list_local", test_iface_list_local); return 0; } /* Helpers */ static semanage_iface_t *get_iface_nth(int idx) { int res; semanage_iface_t **records; semanage_iface_t *iface; unsigned int count; if (idx == I_NULL) return NULL; res = semanage_iface_list(sh, &records, &count); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_FATAL(count >= (unsigned int) idx + 1); iface = records[idx]; for (unsigned int i = 0; i < count; i++) if (i != (unsigned int) idx) semanage_iface_free(records[i]); free(records); return iface; } static semanage_iface_key_t *get_iface_key_nth(int idx) { semanage_iface_key_t *key; semanage_iface_t *iface; int res; if (idx == I_NULL) return NULL; iface = get_iface_nth(idx); res = semanage_iface_key_extract(sh, iface, &key); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); /* cleanup */ semanage_iface_free(iface); return key; } static void add_local_iface(int idx) { semanage_iface_t *iface; semanage_iface_key_t *key = NULL; iface = get_iface_nth(idx); CU_ASSERT_FATAL(semanage_iface_key_extract(sh, iface, &key) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); CU_ASSERT_FATAL(semanage_iface_modify_local(sh, key, iface) >= 0); /* cleanup */ semanage_iface_key_free(key); semanage_iface_free(iface); } static void delete_local_iface(int idx) { semanage_iface_key_t *key = NULL; key = get_iface_key_nth(idx); CU_ASSERT_FATAL(semanage_iface_del_local(sh, key) >= 0); /* cleanup */ semanage_iface_key_free(key); } /* Function semanage_iface_compare */ static void test_iface_compare(void) { semanage_iface_t *iface = NULL; semanage_iface_key_t *key1 = NULL; semanage_iface_key_t *key2 = NULL; int res = 42; /* setup */ setup_handle(SH_CONNECT); iface = get_iface_nth(I_FIRST); key1 = get_iface_key_nth(I_FIRST); CU_ASSERT(semanage_iface_key_create(sh, "qwerty", &key2) >= 0); CU_ASSERT_PTR_NOT_NULL(key2); /* test */ res = semanage_iface_compare(iface, key1); CU_ASSERT(res == 0); res = semanage_iface_compare(iface, key2); CU_ASSERT(res != 0); /* cleanup */ semanage_iface_free(iface); semanage_iface_key_free(key1); semanage_iface_key_free(key2); cleanup_handle(SH_CONNECT); } /* Function semanage_iface_compare2 */ static void test_iface_compare2(void) { semanage_iface_t *iface1 = NULL; semanage_iface_t *iface2 = NULL; semanage_iface_t *iface3 = NULL; int res = 42; /* setup */ setup_handle(SH_CONNECT); iface1 = get_iface_nth(I_FIRST); iface2 = get_iface_nth(I_FIRST); iface3 = get_iface_nth(I_SECOND); /* test */ res = semanage_iface_compare2(iface1, iface2); CU_ASSERT(res == 0); res = semanage_iface_compare2(iface1, iface3); CU_ASSERT(res != 0); /* cleanup */ semanage_iface_free(iface1); semanage_iface_free(iface2); semanage_iface_free(iface3); cleanup_handle(SH_CONNECT); } /* Function semanage_iface_create */ static void test_iface_key_create(void) { semanage_iface_key_t *key = NULL; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_iface_key_create(sh, "asdf", &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* cleanup */ semanage_iface_key_free(key); cleanup_handle(SH_CONNECT); } /* Function semanage_iface_extract */ static void test_iface_key_extract(void) { semanage_iface_t *iface = NULL; semanage_iface_key_t *key = NULL; /* setup */ setup_handle(SH_CONNECT); iface = get_iface_nth(I_FIRST); /* test */ CU_ASSERT(semanage_iface_key_extract(sh, iface, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* cleanup */ semanage_iface_free(iface); semanage_iface_key_free(key); cleanup_handle(SH_CONNECT); } /* Function semanage_iface_get_name, semanage_iface_set_name */ static void test_iface_get_set_name(void) { semanage_iface_t *iface = NULL; /* setup */ setup_handle(SH_CONNECT); iface = get_iface_nth(I_FIRST); /* test */ CU_ASSERT(semanage_iface_set_name(sh, iface, "my_asdf") == 0); CU_ASSERT_STRING_EQUAL(semanage_iface_get_name(iface), "my_asdf"); /* cleanup */ semanage_iface_free(iface); cleanup_handle(SH_CONNECT); } /* Function semanage_iface_get_ifcon, semanage_iface_set_ifcon */ static void test_iface_get_set_ifcon(void) { semanage_iface_t *iface = NULL; semanage_context_t *con1 = NULL; semanage_context_t *con2 = NULL; /* setup */ setup_handle(SH_CONNECT); iface = get_iface_nth(I_FIRST); CU_ASSERT(semanage_context_from_string(sh, "my_user_u:my_role_r:my_type_t:s0", &con1) >= 0); /* test */ CU_ASSERT(semanage_iface_set_ifcon(sh, iface, con1) == 0); con2 = semanage_iface_get_ifcon(iface); CU_ASSERT_CONTEXT_EQUAL(con1, con2); /* cleanup */ semanage_context_free(con1); semanage_iface_free(iface); cleanup_handle(SH_CONNECT); } /* Function semanage_iface_get_msgcon, semanage_iface_set_msgcon */ static void test_iface_get_set_msgcon(void) { semanage_iface_t *iface = NULL; semanage_context_t *con1 = NULL; semanage_context_t *con2 = NULL; /* setup */ setup_handle(SH_CONNECT); iface = get_iface_nth(I_FIRST); CU_ASSERT(semanage_context_from_string(sh, "my_user_u:my_role_r:my_type_t:s0", &con1) >= 0); /* test */ CU_ASSERT(semanage_iface_set_msgcon(sh, iface, con1) == 0); con2 = semanage_iface_get_msgcon(iface); CU_ASSERT_CONTEXT_EQUAL(con1, con2); /* cleanup */ semanage_context_free(con1); semanage_iface_free(iface); cleanup_handle(SH_CONNECT); } /* Function semanage_iface_create */ static void test_iface_create(void) { semanage_iface_t *iface = NULL; semanage_context_t *ifcon = NULL; semanage_context_t *msgcon = NULL; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_iface_create(sh, &iface) >= 0); CU_ASSERT(semanage_iface_set_name(sh, iface, "asdf") >= 0); CU_ASSERT(semanage_context_from_string(sh, "user_u:role_r:type_t:s0", &ifcon) >= 0); CU_ASSERT(semanage_iface_set_ifcon(sh, iface, ifcon) >= 0); CU_ASSERT(semanage_context_from_string(sh, "user_u:role_r:type_t:s0", &msgcon) >= 0); CU_ASSERT(semanage_iface_set_msgcon(sh, iface, msgcon) >= 0); /* cleanup */ semanage_context_free(msgcon); semanage_context_free(ifcon); semanage_iface_free(iface); cleanup_handle(SH_CONNECT); } /* Function semanage_iface_clone */ static void test_iface_clone(void) { semanage_iface_t *iface = NULL; semanage_iface_t *iface_clone = NULL; semanage_context_t *ifcon = NULL; semanage_context_t *ifcon2 = NULL; semanage_context_t *msgcon = NULL; semanage_context_t *msgcon2 = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_iface_create(sh, &iface) >= 0); CU_ASSERT(semanage_iface_set_name(sh, iface, "asdf") >= 0); CU_ASSERT(semanage_context_from_string(sh, "user_u:role_r:if_type_t:s0", &ifcon) >= 0); CU_ASSERT(semanage_iface_set_ifcon(sh, iface, ifcon) >= 0); CU_ASSERT(semanage_context_from_string(sh, "user_u:role_r:msg_type_t:s0", &msgcon) >= 0); CU_ASSERT(semanage_iface_set_msgcon(sh, iface, msgcon) >= 0); /* test */ CU_ASSERT(semanage_iface_clone(sh, iface, &iface_clone) >= 0); CU_ASSERT_STRING_EQUAL(semanage_iface_get_name(iface_clone), "asdf"); ifcon2 = semanage_iface_get_ifcon(iface_clone); CU_ASSERT_CONTEXT_EQUAL(ifcon, ifcon2); msgcon2 = semanage_iface_get_msgcon(iface_clone); CU_ASSERT_CONTEXT_EQUAL(msgcon, msgcon2); /* cleanup */ semanage_context_free(msgcon); semanage_context_free(ifcon); semanage_iface_free(iface); semanage_iface_free(iface_clone); cleanup_handle(SH_CONNECT); } /* Function semanage_iface_query */ static void test_iface_query(void) { semanage_iface_t *iface = NULL; semanage_iface_t *iface_exp = NULL; semanage_iface_key_t *key = NULL; semanage_context_t *con = NULL; semanage_context_t *con_exp = NULL; /* setup */ setup_handle(SH_CONNECT); key = get_iface_key_nth(I_FIRST); iface_exp = get_iface_nth(I_FIRST); /* test */ CU_ASSERT(semanage_iface_query(sh, key, &iface) >= 0); CU_ASSERT_STRING_EQUAL(semanage_iface_get_name(iface), semanage_iface_get_name(iface_exp)); con = semanage_iface_get_ifcon(iface); con_exp = semanage_iface_get_ifcon(iface_exp); CU_ASSERT_CONTEXT_EQUAL(con, con_exp); con = semanage_iface_get_msgcon(iface); con_exp = semanage_iface_get_msgcon(iface_exp); CU_ASSERT_CONTEXT_EQUAL(con, con_exp); /* cleanup */ semanage_iface_key_free(key); semanage_iface_free(iface); semanage_iface_free(iface_exp); cleanup_handle(SH_CONNECT); } /* Function semanage_iface_exists */ static void test_iface_exists(void) { semanage_iface_key_t *key1 = NULL; semanage_iface_key_t *key2 = NULL; int resp = 42; /* setup */ setup_handle(SH_CONNECT); key1 = get_iface_key_nth(I_FIRST); CU_ASSERT(semanage_iface_key_create(sh, "asdf", &key2) >= 0); /* test */ CU_ASSERT(semanage_iface_exists(sh, key1, &resp) >= 0); CU_ASSERT(resp); CU_ASSERT(semanage_iface_exists(sh, key2, &resp) >= 0); CU_ASSERT(!resp); /* cleanup */ semanage_iface_key_free(key1); semanage_iface_key_free(key2); cleanup_handle(SH_CONNECT); } /* Function semanage_iface_count */ static void test_iface_count(void) { unsigned int count = 42; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_iface_count(sh, &count) >= 0); CU_ASSERT(count == IFACE_COUNT); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_iface_iterate */ static unsigned int counter_iface_iterate = 0; static int handler_iface_iterate(__attribute__((unused)) const semanage_iface_t *record, __attribute__((unused)) void *varg) { counter_iface_iterate++; return 0; } static void test_iface_iterate(void) { /* setup */ setup_handle(SH_CONNECT); /* test */ semanage_iface_iterate(sh, handler_iface_iterate, NULL); CU_ASSERT(counter_iface_iterate == IFACE_COUNT); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_iface_list */ static void test_iface_list(void) { semanage_iface_t **records = NULL; unsigned int count = 42; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_iface_list(sh, &records, &count) >= 0); CU_ASSERT(count == IFACE_COUNT); for (unsigned int i = 0; i < count; i++) CU_ASSERT_PTR_NOT_NULL(records[i]); for (unsigned int i = 0; i < count; i++) semanage_iface_free(records[i]); free(records); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_iface_modify_local, semanage_iface_del_local, * semanage_iface_query_local */ static void test_iface_modify_del_query_local(void) { semanage_iface_t *iface; semanage_iface_t *iface_local; semanage_iface_key_t *key = NULL; /* setup */ setup_handle(SH_TRANS); iface = get_iface_nth(I_FIRST); CU_ASSERT(semanage_iface_key_extract(sh, iface, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* test */ CU_ASSERT(semanage_iface_modify_local(sh, key, iface) >= 0); /* write changes to file */ helper_commit(); helper_begin_transaction(); CU_ASSERT(semanage_iface_query_local(sh, key, &iface_local) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(iface_local); semanage_iface_free(iface_local); CU_ASSERT(semanage_iface_del_local(sh, key) >= 0); CU_ASSERT(semanage_iface_query_local(sh, key, &iface_local) < 0); /* cleanup */ semanage_iface_key_free(key); semanage_iface_free(iface); cleanup_handle(SH_TRANS); } /* Function semanage_iface_exists_local */ static void test_iface_exists_local(void) { semanage_iface_key_t *key1 = NULL; semanage_iface_key_t *key2 = NULL; int resp = 42; /* setup */ setup_handle(SH_TRANS); add_local_iface(I_FIRST); key1 = get_iface_key_nth(I_FIRST); key2 = get_iface_key_nth(I_SECOND); /* test */ CU_ASSERT(semanage_iface_exists_local(sh, key1, &resp) >= 0); CU_ASSERT(resp); CU_ASSERT(semanage_iface_exists_local(sh, key2, &resp) >= 0); CU_ASSERT(!resp); /* cleanup */ CU_ASSERT(semanage_iface_del_local(sh, key1) >= 0); semanage_iface_key_free(key1); semanage_iface_key_free(key2); cleanup_handle(SH_TRANS); } /* Function semanage_iface_count_local */ static void test_iface_count_local(void) { unsigned int count = 42; /* setup */ setup_handle(SH_TRANS); /* test */ CU_ASSERT(semanage_iface_count_local(sh, &count) >= 0); CU_ASSERT(count == 0); add_local_iface(I_FIRST); CU_ASSERT(semanage_iface_count_local(sh, &count) >= 0); CU_ASSERT(count == 1); add_local_iface(I_SECOND); CU_ASSERT(semanage_iface_count_local(sh, &count) >= 0); CU_ASSERT(count == 2); delete_local_iface(I_SECOND); CU_ASSERT(semanage_iface_count_local(sh, &count) >= 0); CU_ASSERT(count == 1); delete_local_iface(I_FIRST); CU_ASSERT(semanage_iface_count_local(sh, &count) >= 0); CU_ASSERT(count == 0); /* cleanup */ cleanup_handle(SH_TRANS); } /* Function semanage_iface_iterate_local */ static unsigned int counter_iface_iterate_local = 0; static int handler_iface_iterate_local(__attribute__((unused)) const semanage_iface_t *record, __attribute__((unused)) void *varg) { counter_iface_iterate_local++; return 0; } static void test_iface_iterate_local(void) { /* setup */ setup_handle(SH_TRANS); add_local_iface(I_FIRST); add_local_iface(I_SECOND); add_local_iface(I_THIRD); /* test */ semanage_iface_iterate_local(sh, handler_iface_iterate_local, NULL); CU_ASSERT(counter_iface_iterate_local == 3); /* cleanup */ delete_local_iface(I_FIRST); delete_local_iface(I_SECOND); delete_local_iface(I_THIRD); cleanup_handle(SH_TRANS); } /* Function semanage_iface_list_local */ static void test_iface_list_local(void) { semanage_iface_t **records = NULL; unsigned int count = 42; /* setup */ setup_handle(SH_TRANS); add_local_iface(I_FIRST); add_local_iface(I_SECOND); add_local_iface(I_THIRD); /* test */ CU_ASSERT(semanage_iface_list_local(sh, &records, &count) >= 0); CU_ASSERT(count == 3); for (unsigned int i = 0; i < count; i++) CU_ASSERT_PTR_NOT_NULL(records[i]); /* cleanup */ for (unsigned int i = 0; i < count; i++) semanage_iface_free(records[i]); free(records); delete_local_iface(I_FIRST); delete_local_iface(I_SECOND); delete_local_iface(I_THIRD); cleanup_handle(SH_TRANS); } libsemanage-3.8.1/tests/test_iface.cil000066400000000000000000000017551476211737200177550ustar00rootroot00000000000000(typeattribute cil_gen_require) (roleattribute cil_gen_require) (handleunknown allow) (mls true) (policycap network_peer_controls) (policycap open_perms) (sid security) (sidorder (security)) (sensitivity s0) (sensitivityorder (s0)) (user system_u) (userrole system_u object_r) (userlevel system_u (s0)) (userrange system_u ((s0) (s0))) (role object_r) (roletype object_r first_netif_t) (roletype object_r second_netif_t) (roletype object_r third_netif_t) (type first_netif_t) (type second_netif_t) (type third_netif_t) (sidcontext security (system_u object_r first_netif_t ((s0) (s0)))) (class netif (tcp_recv)) (classorder (netif)) (allow first_netif_t self (netif (tcp_recv))) (netifcon eth0 (system_u object_r first_netif_t ((s0) (s0))) (system_u object_r first_netif_t ((s0) (s0)))) (netifcon eth1 (system_u object_r second_netif_t ((s0) (s0))) (system_u object_r second_netif_t ((s0) (s0)))) (netifcon eth2 (system_u object_r third_netif_t ((s0) (s0))) (system_u object_r third_netif_t ((s0) (s0)))) libsemanage-3.8.1/tests/test_iface.h000066400000000000000000000017631476211737200174340ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 __TEST_IFACE_H__ #define __TEST_IFACE_H__ #include int iface_test_init(void); int iface_test_cleanup(void); int iface_add_tests(CU_pSuite suite); #endif libsemanage-3.8.1/tests/test_node.c000066400000000000000000000517021476211737200173030ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 "utilities.h" #include "test_node.h" #define NODE_COUNT 3 #define NODE1_ADDR "192.168.0.0" #define NODE1_MASK "255.255.255.0" #define NODE1_PROTO SEPOL_PROTO_IP4 #define NODE1_CONTEXT "system_u:object_r:first_node_t:s0" #define NODE2_ADDR "2001:db8:85a3::8a2e:370:7334" #define NODE2_MASK "2001:db8:85a3::8a2e:370:7334" #define NODE2_PROTO SEPOL_PROTO_IP6 #define NODE2_CONTEXT "system_u:object_r:second_node_t:s0" #define NODE3_ADDR "127.0.0.1" #define NODE3_MASK "255.255.0.0" #define NODE3_PROTO SEPOL_PROTO_IP4 #define NODE3_CONTEXT "system_u:object_r:third_node_t:s0" /* node_record.h */ static void test_node_compare(void); static void test_node_compare2(void); static void test_node_key_create(void); static void test_node_key_extract(void); static void test_node_get_set_addr(void); static void test_node_get_set_addr_bytes(void); static void test_node_get_set_mask(void); static void test_node_get_set_mask_bytes(void); static void test_node_get_set_proto(void); static void test_node_get_proto_str(void); static void test_node_get_set_con(void); static void test_node_create(void); static void test_node_clone(void); /* nodes_policy.h */ static void test_node_query(void); static void test_node_exists(void); static void test_node_count(void); static void test_node_iterate(void); static void test_node_list(void); /* nodes_local.h */ static void test_node_modify_del_query_local(void); static void test_node_exists_local(void); static void test_node_count_local(void); static void test_node_iterate_local(void); static void test_node_list_local(void); int node_test_init(void) { if (create_test_store() < 0) { fprintf(stderr, "Could not create test store\n"); return 1; } if (write_test_policy_from_file("test_node.policy") < 0) { fprintf(stderr, "Could not write test policy\n"); return 1; } return 0; } int node_test_cleanup(void) { if (destroy_test_store() < 0) { fprintf(stderr, "Could destroy test store\n"); return 1; } return 0; } int node_add_tests(CU_pSuite suite) { CU_add_test(suite, "node_compare", test_node_compare); CU_add_test(suite, "node_compare2", test_node_compare2); CU_add_test(suite, "node_key_create", test_node_key_create); CU_add_test(suite, "node_key_extract", test_node_key_extract); CU_add_test(suite, "node_get_set_addr", test_node_get_set_addr); CU_add_test(suite, "node_get_set_addr_bytes", test_node_get_set_addr_bytes); CU_add_test(suite, "node_get_set_mask", test_node_get_set_mask); CU_add_test(suite, "node_get_set_mask_bytes", test_node_get_set_mask_bytes); CU_add_test(suite, "node_get_set_proto", test_node_get_set_proto); CU_add_test(suite, "node_get_proto_str", test_node_get_proto_str); CU_add_test(suite, "node_get_set_con", test_node_get_set_con); CU_add_test(suite, "node_create", test_node_create); CU_add_test(suite, "node_clone", test_node_clone); CU_add_test(suite, "node_query", test_node_query); CU_add_test(suite, "node_exists", test_node_exists); CU_add_test(suite, "node_count", test_node_count); CU_add_test(suite, "node_iterate", test_node_iterate); CU_add_test(suite, "node_list", test_node_list); CU_add_test(suite, "node_modify_del_query_local", test_node_modify_del_query_local); CU_add_test(suite, "node_exists_local", test_node_exists_local); CU_add_test(suite, "node_count_local", test_node_count_local); CU_add_test(suite, "node_iterate_local", test_node_iterate_local); CU_add_test(suite, "node_list_local", test_node_list_local); return 0; } /* Helpers */ static semanage_node_t *get_node_nth(int idx) { semanage_node_t **records; semanage_node_t *node; unsigned int count; if (idx == I_NULL) return NULL; CU_ASSERT_FATAL(semanage_node_list(sh, &records, &count) >= 0); CU_ASSERT_FATAL(count >= (unsigned int) idx + 1); node = records[idx]; for (unsigned int i = 0; i < count; i++) if (i != (unsigned int) idx) semanage_node_free(records[i]); free(records); return node; } static semanage_node_key_t *get_node_key_nth(int idx) { semanage_node_key_t *key; semanage_node_t *node; int res; if (idx == I_NULL) return NULL; node = get_node_nth(idx); res = semanage_node_key_extract(sh, node, &key); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); semanage_node_free(node); return key; } static void add_local_node(int idx) { semanage_node_t *node; semanage_node_key_t *key = NULL; node = get_node_nth(idx); CU_ASSERT_FATAL(semanage_node_key_extract(sh, node, &key) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); CU_ASSERT_FATAL(semanage_node_modify_local(sh, key, node) >= 0); /* cleanup */ semanage_node_key_free(key); semanage_node_free(node); } static void delete_local_node(int idx) { semanage_node_key_t *key = NULL; key = get_node_key_nth(idx); CU_ASSERT_FATAL(semanage_node_del_local(sh, key) >= 0); /* cleanup */ semanage_node_key_free(key); } /* Function semanage_node_compare */ static void test_node_compare(void) { semanage_node_t *node = NULL; semanage_node_key_t *key1 = NULL; semanage_node_key_t *key2 = NULL; int res = 42; /* setup */ setup_handle(SH_CONNECT); node = get_node_nth(I_FIRST); key1 = get_node_key_nth(I_FIRST); CU_ASSERT(semanage_node_key_create(sh, "192.168.0.1", "255.255.0.0", SEMANAGE_PROTO_IP4, &key2) >= 0); CU_ASSERT_PTR_NOT_NULL(key2); /* test */ res = semanage_node_compare(node, key1); CU_ASSERT(res == 0); res = semanage_node_compare(node, key2); CU_ASSERT(res != 0); /* cleanup */ semanage_node_free(node); semanage_node_key_free(key1); semanage_node_key_free(key2); cleanup_handle(SH_CONNECT); } /* Function semanage_node_compare2 */ static void test_node_compare2(void) { semanage_node_t *node1 = NULL; semanage_node_t *node2 = NULL; semanage_node_t *node3 = NULL; int res = 42; /* setup */ setup_handle(SH_CONNECT); node1 = get_node_nth(I_FIRST); node2 = get_node_nth(I_FIRST); node3 = get_node_nth(I_SECOND); /* test */ res = semanage_node_compare2(node1, node2); CU_ASSERT(res == 0); res = semanage_node_compare2(node1, node3); CU_ASSERT(res != 0); /* cleanup */ semanage_node_free(node1); semanage_node_free(node2); semanage_node_free(node3); cleanup_handle(SH_CONNECT); } /* Function semanage_node_key_create */ static void test_node_key_create(void) { semanage_node_key_t *key = NULL; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_node_key_create(sh, "127.0.0.1", "255.255.255.255", SEMANAGE_PROTO_IP4, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* cleanup */ semanage_node_key_free(key); cleanup_handle(SH_CONNECT); } /* Function semanage_node_key_extract */ static void test_node_key_extract(void) { semanage_node_t *node = NULL; semanage_node_key_t *key = NULL; /* setup */ setup_handle(SH_CONNECT); node = get_node_nth(I_FIRST); /* test */ CU_ASSERT(semanage_node_key_extract(sh, node, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* cleanup */ semanage_node_free(node); semanage_node_key_free(key); cleanup_handle(SH_CONNECT); } /* Function semanage_node_get_addr, semanage_node_set_addr */ static void test_node_get_set_addr(void) { semanage_node_t *node = NULL; char *addr = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_node_create(sh, &node) >= 0); /* test */ CU_ASSERT(semanage_node_set_addr(sh, node, SEMANAGE_PROTO_IP4, "192.168.0.1") == 0); CU_ASSERT(semanage_node_get_addr(sh, node, &addr) >= 0); CU_ASSERT_PTR_NOT_NULL(addr); assert(addr); CU_ASSERT_STRING_EQUAL(addr, "192.168.0.1"); /* cleanup */ free(addr); semanage_node_free(node); cleanup_handle(SH_CONNECT); } /* Function semanage_node_get_addr_bytes, semanage_node_set_addr_bytes */ static void test_node_get_set_addr_bytes(void) { semanage_node_t *node = NULL; char addr1[] = { 192, 168, 0, 1 }; size_t addr1_size = sizeof(addr1); char *addr2 = NULL; size_t addr2_size = 0; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_node_create(sh, &node) >= 0); /* test */ CU_ASSERT(semanage_node_set_addr_bytes(sh, node, addr1, addr1_size) == 0); CU_ASSERT(semanage_node_get_addr_bytes(sh, node, &addr2, &addr2_size) >= 0); CU_ASSERT_PTR_NOT_NULL(addr2); assert(addr2); for (size_t i = 0; i < addr2_size; i++) CU_ASSERT(addr1[i] == addr2[i]); /* cleanup */ free(addr2); semanage_node_free(node); cleanup_handle(SH_CONNECT); } /* Function semanage_node_get_mask, semanage_node_set_mask */ static void test_node_get_set_mask(void) { semanage_node_t *node = NULL; char *mask = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_node_create(sh, &node) >= 0); /* test */ CU_ASSERT(semanage_node_set_mask(sh, node, SEMANAGE_PROTO_IP4, "255.255.255.0") == 0); CU_ASSERT(semanage_node_get_mask(sh, node, &mask) >= 0); CU_ASSERT_PTR_NOT_NULL(mask); assert(mask); CU_ASSERT_STRING_EQUAL(mask, "255.255.255.0"); /* cleanup */ free(mask); semanage_node_free(node); cleanup_handle(SH_CONNECT); } /* Function semanage_node_get_mask_bytes, semanage_node_set_mask_bytes */ static void test_node_get_set_mask_bytes(void) { semanage_node_t *node = NULL; char mask1[] = { 255, 255, 255, 0 }; size_t mask1_size = sizeof(mask1); char *mask2 = NULL; size_t mask2_size = 0; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_node_create(sh, &node) >= 0); /* test */ CU_ASSERT(semanage_node_set_mask_bytes(sh, node, mask1, mask1_size) == 0); CU_ASSERT(semanage_node_get_mask_bytes(sh, node, &mask2, &mask2_size) >= 0); CU_ASSERT_PTR_NOT_NULL(mask2); assert(mask2); for (size_t i = 0; i < mask2_size; i++) CU_ASSERT(mask1[i] == mask2[i]); /* cleanup */ free(mask2); semanage_node_free(node); cleanup_handle(SH_CONNECT); } /* Function semanage_node_get_proto, semanage_node_set_proto */ static void test_node_get_set_proto(void) { semanage_node_t *node = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_node_create(sh, &node) >= 0); /* test */ semanage_node_set_proto(node, SEMANAGE_PROTO_IP4); CU_ASSERT(semanage_node_get_proto(node) == SEMANAGE_PROTO_IP4); /* cleanup */ semanage_node_free(node); cleanup_handle(SH_CONNECT); } /* Function semanage_node_get_proto_str */ static void test_node_get_proto_str(void) { CU_ASSERT_STRING_EQUAL(semanage_node_get_proto_str(SEMANAGE_PROTO_IP4), "ipv4"); CU_ASSERT_STRING_EQUAL(semanage_node_get_proto_str(SEMANAGE_PROTO_IP6), "ipv6"); } /* Function semanage_node_get_con, semanage_node_set_con */ static void test_node_get_set_con(void) { semanage_node_t *node = NULL; semanage_context_t *con1 = NULL; semanage_context_t *con2 = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_node_create(sh, &node) >= 0); CU_ASSERT(semanage_context_from_string(sh, "my_user_u:my_role_r:my_type_t:s0", &con1) >= 0); /* test */ CU_ASSERT(semanage_node_set_con(sh, node, con1) == 0); con2 = semanage_node_get_con(node); CU_ASSERT_CONTEXT_EQUAL(con1, con2); /* cleanup */ semanage_context_free(con1); semanage_node_free(node); cleanup_handle(SH_CONNECT); } /* Function semanage_node_create */ static void test_node_create(void) { semanage_node_t *node = NULL; semanage_context_t *con = NULL; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_node_create(sh, &node) >= 0); CU_ASSERT(semanage_node_set_addr(sh, node, SEMANAGE_PROTO_IP4, "127.0.0.1") >= 0); CU_ASSERT(semanage_node_set_mask(sh, node, SEMANAGE_PROTO_IP4, "255.255.255.0") >= 0); semanage_node_set_proto(node, SEMANAGE_PROTO_IP4); CU_ASSERT(semanage_context_from_string(sh, "user_u:role_r:type_t:s0", &con) >= 0); CU_ASSERT(semanage_node_set_con(sh, node, con) >= 0); /* cleanup */ semanage_context_free(con); semanage_node_free(node); cleanup_handle(SH_CONNECT); } /* Function semanage_node_clone */ static void test_node_clone(void) { semanage_node_t *node = NULL; semanage_node_t *node_clone = NULL; semanage_context_t *con = NULL; semanage_context_t *con2 = NULL; const char *addr1 = "127.0.0.1"; char *addr2 = NULL; const char *mask1 = "255.255.255.0"; char *mask2 = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_node_create(sh, &node) >= 0); CU_ASSERT(semanage_node_set_addr(sh, node, SEMANAGE_PROTO_IP4, addr1) >= 0); CU_ASSERT(semanage_node_set_mask(sh, node, SEMANAGE_PROTO_IP4, mask1) >= 0); semanage_node_set_proto(node, SEMANAGE_PROTO_IP4); CU_ASSERT(semanage_context_from_string(sh, "user_u:role_r:type_t:s0", &con) >= 0); CU_ASSERT(semanage_node_set_con(sh, node, con) >= 0); /* test */ CU_ASSERT(semanage_node_clone(sh, node, &node_clone) >= 0); CU_ASSERT(semanage_node_get_addr(sh, node_clone, &addr2) >= 0); CU_ASSERT_PTR_NOT_NULL(addr2); assert(addr2); CU_ASSERT_STRING_EQUAL(addr1, addr2); CU_ASSERT(semanage_node_get_mask(sh, node_clone, &mask2) >= 0); CU_ASSERT_PTR_NOT_NULL(mask2); assert(mask2); CU_ASSERT_STRING_EQUAL(mask1, mask2); CU_ASSERT(semanage_node_get_proto(node_clone) == SEMANAGE_PROTO_IP4); con2 = semanage_node_get_con(node_clone); CU_ASSERT_CONTEXT_EQUAL(con, con2); /* cleanup */ free(mask2); free(addr2); semanage_context_free(con); semanage_node_free(node); semanage_node_free(node_clone); cleanup_handle(SH_CONNECT); } /* Function semanage_node_query */ static void test_node_query(void) { semanage_node_t *node = NULL; semanage_node_t *node_exp = NULL; semanage_node_key_t *key = NULL; char *str = NULL; char *str_exp = NULL; semanage_context_t *con = NULL; semanage_context_t *con_exp = NULL; /* setup */ setup_handle(SH_CONNECT); key = get_node_key_nth(I_FIRST); node_exp = get_node_nth(I_FIRST); /* test */ CU_ASSERT(semanage_node_query(sh, key, &node) >= 0); CU_ASSERT(semanage_node_get_addr(sh, node, &str) >= 0); CU_ASSERT(semanage_node_get_addr(sh, node_exp, &str_exp) >= 0); CU_ASSERT_STRING_EQUAL(str, str_exp); free(str); free(str_exp); CU_ASSERT(semanage_node_get_mask(sh, node, &str) >= 0); CU_ASSERT(semanage_node_get_mask(sh, node_exp, &str_exp) >= 0); CU_ASSERT_STRING_EQUAL(str, str_exp); free(str); free(str_exp); CU_ASSERT(semanage_node_get_proto(node) == semanage_node_get_proto(node_exp)); con = semanage_node_get_con(node); con_exp = semanage_node_get_con(node_exp); CU_ASSERT_CONTEXT_EQUAL(con, con_exp); /* cleanup */ semanage_node_key_free(key); semanage_node_free(node_exp); semanage_node_free(node); cleanup_handle(SH_CONNECT); } /* Function semanage_node_exists */ static void test_node_exists(void) { semanage_node_key_t *key1 = NULL; semanage_node_key_t *key2 = NULL; int resp = 42; /* setup */ setup_handle(SH_CONNECT); key1 = get_node_key_nth(I_FIRST); CU_ASSERT(semanage_node_key_create(sh, "1.2.3.4", "255.255.0.0", SEMANAGE_PROTO_IP4, &key2) >= 0); /* test */ CU_ASSERT(semanage_node_exists(sh, key1, &resp) >= 0); CU_ASSERT(resp); CU_ASSERT(semanage_node_exists(sh, key2, &resp) >= 0); CU_ASSERT(!resp); /* cleanup */ semanage_node_key_free(key1); semanage_node_key_free(key2); cleanup_handle(SH_CONNECT); } /* Function semanage_node_count */ static void test_node_count(void) { unsigned int count = 42; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_node_count(sh, &count) >= 0); CU_ASSERT(count == NODE_COUNT); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_node_iterate */ static unsigned int counter_node_iterate = 0; static int handler_node_iterate(__attribute__((unused)) const semanage_node_t *record, __attribute__((unused)) void *varg) { counter_node_iterate++; return 0; } static void test_node_iterate(void) { /* setup */ setup_handle(SH_CONNECT); /* test */ semanage_node_iterate(sh, handler_node_iterate, NULL); CU_ASSERT(counter_node_iterate == NODE_COUNT); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_node_list */ static void test_node_list(void) { semanage_node_t **records = NULL; unsigned int count = 42; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_node_list(sh, &records, &count) >= 0); CU_ASSERT(count == NODE_COUNT); for (unsigned int i = 0; i < count; i++) CU_ASSERT_PTR_NOT_NULL(records[i]); for (unsigned int i = 0; i < count; i++) semanage_node_free(records[i]); free(records); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_node_modify_local, semanage_node_del_local, * semanage_node_query_local */ static void test_node_modify_del_query_local(void) { semanage_node_t *node; semanage_node_t *node_local; semanage_node_t *node_tmp; semanage_node_key_t *key = NULL; semanage_node_key_t *key_tmp = NULL; /* setup */ setup_handle(SH_TRANS); node = get_node_nth(I_FIRST); CU_ASSERT(semanage_node_key_extract(sh, node, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* add second record, so that semanage_node_compare2_qsort * will be called */ node_tmp = get_node_nth(I_FIRST); CU_ASSERT(semanage_node_set_addr(sh, node_tmp, SEMANAGE_PROTO_IP4, "10.0.0.1") >= 0); CU_ASSERT(semanage_node_key_extract(sh, node_tmp, &key_tmp) >= 0); CU_ASSERT_PTR_NOT_NULL(key_tmp); /* test */ CU_ASSERT(semanage_node_modify_local(sh, key, node) >= 0); CU_ASSERT(semanage_node_modify_local(sh, key_tmp, node_tmp) >= 0); /* write changes to file */ helper_commit(); helper_begin_transaction(); CU_ASSERT(semanage_node_query_local(sh, key, &node_local) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(node_local); semanage_node_free(node_local); CU_ASSERT(semanage_node_del_local(sh, key) >= 0); CU_ASSERT(semanage_node_del_local(sh, key_tmp) >= 0); CU_ASSERT(semanage_node_query_local(sh, key, &node_local) < 0); /* cleanup */ semanage_node_key_free(key_tmp); semanage_node_key_free(key); semanage_node_free(node); semanage_node_free(node_tmp); cleanup_handle(SH_TRANS); } /* Function semanage_node_exists_local */ static void test_node_exists_local(void) { semanage_node_key_t *key1 = NULL; semanage_node_key_t *key2 = NULL; int resp = 42; /* setup */ setup_handle(SH_TRANS); add_local_node(I_FIRST); key1 = get_node_key_nth(I_FIRST); key2 = get_node_key_nth(I_SECOND); /* test */ CU_ASSERT(semanage_node_exists_local(sh, key1, &resp) >= 0); CU_ASSERT(resp); CU_ASSERT(semanage_node_exists_local(sh, key2, &resp) >= 0); CU_ASSERT(!resp); /* cleanup */ CU_ASSERT(semanage_node_del_local(sh, key1) >= 0); semanage_node_key_free(key1); semanage_node_key_free(key2); cleanup_handle(SH_TRANS); } /* Function semanage_node_count_local */ static void test_node_count_local(void) { unsigned int count = 42; /* setup */ setup_handle(SH_TRANS); /* test */ CU_ASSERT(semanage_node_count_local(sh, &count) >= 0); CU_ASSERT(count == 0); add_local_node(I_FIRST); CU_ASSERT(semanage_node_count_local(sh, &count) >= 0); CU_ASSERT(count == 1); add_local_node(I_SECOND); CU_ASSERT(semanage_node_count_local(sh, &count) >= 0); CU_ASSERT(count == 2); delete_local_node(I_SECOND); CU_ASSERT(semanage_node_count_local(sh, &count) >= 0); CU_ASSERT(count == 1); delete_local_node(I_FIRST); CU_ASSERT(semanage_node_count_local(sh, &count) >= 0); CU_ASSERT(count == 0); /* cleanup */ cleanup_handle(SH_TRANS); } /* Function semanage_node_iterate_local */ static unsigned int counter_node_iterate_local = 0; static int handler_node_iterate_local(__attribute__((unused)) const semanage_node_t *record, __attribute__((unused)) void *varg) { counter_node_iterate_local++; return 0; } static void test_node_iterate_local(void) { /* setup */ setup_handle(SH_TRANS); add_local_node(I_FIRST); add_local_node(I_SECOND); add_local_node(I_THIRD); /* test */ semanage_node_iterate_local(sh, handler_node_iterate_local, NULL); CU_ASSERT(counter_node_iterate_local == 3); /* cleanup */ delete_local_node(I_FIRST); delete_local_node(I_SECOND); delete_local_node(I_THIRD); cleanup_handle(SH_TRANS); } /* Function semanage_node_list_local */ static void test_node_list_local(void) { semanage_node_t **records = NULL; unsigned int count = 42; /* setup */ setup_handle(SH_TRANS); add_local_node(I_FIRST); add_local_node(I_SECOND); add_local_node(I_THIRD); /* test */ CU_ASSERT(semanage_node_list_local(sh, &records, &count) >= 0); CU_ASSERT(count == 3); for (unsigned int i = 0; i < count; i++) CU_ASSERT_PTR_NOT_NULL(records[i]); /* cleanup */ for (unsigned int i = 0; i < count; i++) semanage_node_free(records[i]); free(records); delete_local_node(I_FIRST); delete_local_node(I_SECOND); delete_local_node(I_THIRD); cleanup_handle(SH_TRANS); } libsemanage-3.8.1/tests/test_node.cil000066400000000000000000000016701476211737200176270ustar00rootroot00000000000000(typeattribute cil_gen_require) (roleattribute cil_gen_require) (handleunknown allow) (mls true) (policycap network_peer_controls) (policycap open_perms) (sid security) (sidorder (security)) (sensitivity s0) (sensitivityorder (s0)) (user system_u) (userrole system_u object_r) (userlevel system_u (s0)) (userrange system_u ((s0) (s0))) (role object_r) (roletype object_r first_node_t) (roletype object_r second_node_t) (roletype object_r third_node_t) (type first_node_t) (type second_node_t) (type third_node_t) (sidcontext security (system_u object_r first_node_t ((s0) (s0)))) (class node (tcp_recv)) (classorder (node)) (allow first_node_t self (node (tcp_recv))) (nodecon (192.168.0.0) (255.255.255.0) (system_u object_r first_node_t ((s0) (s0)))) (nodecon (2001:db8:85a3::8a2e:370:7334) (2001:db8:85a3::8a2e:370:7334) (system_u object_r second_node_t ((s0) (s0)))) (nodecon (127.0.0.1) (255.255.0.0) (system_u object_r third_node_t ((s0) (s0)))) libsemanage-3.8.1/tests/test_node.h000066400000000000000000000017561476211737200173140ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 __TEST_NODE_H__ #define __TEST_NODE_H__ #include int node_test_init(void); int node_test_cleanup(void); int node_add_tests(CU_pSuite suite); #endif libsemanage-3.8.1/tests/test_other.c000066400000000000000000000074571476211737200175070ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 "utilities.h" #include "test_other.h" /* context_record.h */ void test_semanage_context(void); /* debug.h */ void test_debug(void); int other_test_init(void) { return 0; } int other_test_cleanup(void) { return 0; } int other_add_tests(CU_pSuite suite) { CU_add_test(suite, "semanage_context", test_semanage_context); CU_add_test(suite, "debug", test_debug); return 0; } /* Function semanage_context_get_user, semanage_context_set_user, * semanage_context_get_role, semanage_context_set_role, * semanage_context_get_type, semanage_context_set_type, * semanage_context_get_mls, semanage_context_set_mls, * semanage_context_create, semanage_context_clone, * semanage_context_free, semanage_context_from_string * semanage_context_to_string */ void test_semanage_context(void) { semanage_context_t *con = NULL; semanage_context_t *con_clone = NULL; char *str = NULL; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_context_create(sh, &con) >= 0); CU_ASSERT(semanage_context_set_user(sh, con, "user_u") >= 0); CU_ASSERT_STRING_EQUAL(semanage_context_get_user(con), "user_u"); CU_ASSERT(semanage_context_set_role(sh, con, "role_r") >= 0); CU_ASSERT_STRING_EQUAL(semanage_context_get_role(con), "role_r"); CU_ASSERT(semanage_context_set_type(sh, con, "type_t") >= 0); CU_ASSERT_STRING_EQUAL(semanage_context_get_type(con), "type_t"); CU_ASSERT(semanage_context_set_mls(sh, con, "s0") >= 0); CU_ASSERT_STRING_EQUAL(semanage_context_get_mls(con), "s0"); CU_ASSERT(semanage_context_to_string(sh, con, &str) >= 0); CU_ASSERT_PTR_NOT_NULL(str); assert(str); CU_ASSERT_STRING_EQUAL(str, "user_u:role_r:type_t:s0"); semanage_context_free(con); con = NULL; CU_ASSERT(semanage_context_from_string(sh, "my_u:my_r:my_t:s0", &con) >= 0); CU_ASSERT_STRING_EQUAL(semanage_context_get_user(con), "my_u"); CU_ASSERT_STRING_EQUAL(semanage_context_get_role(con), "my_r"); CU_ASSERT_STRING_EQUAL(semanage_context_get_type(con), "my_t"); CU_ASSERT_STRING_EQUAL(semanage_context_get_mls(con), "s0"); CU_ASSERT(semanage_context_clone(sh, con, &con_clone) >= 0); CU_ASSERT_STRING_EQUAL(semanage_context_get_user(con_clone), "my_u"); CU_ASSERT_STRING_EQUAL(semanage_context_get_role(con_clone), "my_r"); CU_ASSERT_STRING_EQUAL(semanage_context_get_type(con_clone), "my_t"); CU_ASSERT_STRING_EQUAL(semanage_context_get_mls(con_clone), "s0"); /* cleanup */ free(str); semanage_context_free(con); semanage_context_free(con_clone); cleanup_handle(SH_CONNECT); } /* Function semanage_msg_default_handler */ void test_debug(void) { semanage_module_info_t *modinfo = NULL; /* setup */ sh = semanage_handle_create(); CU_ASSERT_PTR_NOT_NULL(sh); CU_ASSERT(semanage_connect(sh) >= 0); CU_ASSERT(semanage_module_info_create(sh, &modinfo) >= 0); /* test */ CU_ASSERT(semanage_module_info_set_priority(sh, modinfo, (uint16_t)-42) < 0); /* cleanup */ semanage_module_info_destroy(sh, modinfo); free(modinfo); CU_ASSERT(semanage_disconnect(sh) >= 0); semanage_handle_destroy(sh); } libsemanage-3.8.1/tests/test_other.h000066400000000000000000000017631476211737200175060ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 __TEST_OTHER_H__ #define __TEST_OTHER_H__ #include int other_test_init(void); int other_test_cleanup(void); int other_add_tests(CU_pSuite suite); #endif libsemanage-3.8.1/tests/test_port.c000066400000000000000000000520341476211737200173410ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 "utilities.h" #include "test_port.h" #define PORT_COUNT 3 #define PORT1_LOW 80 #define PORT1_HIGH 80 #define PORT1_PROTO SEPOL_PROTO_TCP #define PORT2_LOW 1 #define PORT2_HIGH 1023 #define PORT2_PROTO SEPOL_PROTO_UDP #define PORT3_LOW 12345 #define PORT3_HIGH 12345 #define PORT3_PROTO SEPOL_PROTO_TCP /* port_record.h */ static void test_port_compare(void); static void test_port_compare2(void); static void test_port_key_create(void); static void test_port_key_extract(void); static void test_port_get_set_proto(void); static void test_port_get_proto_str(void); static void test_port_get_set_port(void); static void test_port_get_set_con(void); static void test_port_create(void); static void test_port_clone(void); /* ports_policy.h */ static void test_port_query(void); static void test_port_exists(void); static void test_port_count(void); static void test_port_iterate(void); static void test_port_list(void); /* ports_local.h */ static void test_port_modify_del_local(void); static void test_port_query_local(void); static void test_port_exists_local(void); static void test_port_count_local(void); static void test_port_iterate_local(void); static void test_port_list_local(void); /* internal */ static void test_port_validate_local(void); int port_test_init(void) { if (create_test_store() < 0) { fprintf(stderr, "Could not create test store\n"); return 1; } if (write_test_policy_from_file("test_port.policy") < 0) { fprintf(stderr, "Could not write test policy\n"); return 1; } return 0; } int port_test_cleanup(void) { if (destroy_test_store() < 0) { fprintf(stderr, "Could not destroy test store\n"); return 1; } return 0; } int port_add_tests(CU_pSuite suite) { CU_add_test(suite, "port_compare", test_port_compare); CU_add_test(suite, "port_compare2", test_port_compare2); CU_add_test(suite, "port_key_create", test_port_key_create); CU_add_test(suite, "port_key_extract", test_port_key_extract); CU_add_test(suite, "port_get_set_proto", test_port_get_set_proto); CU_add_test(suite, "port_get_proto_str", test_port_get_proto_str); CU_add_test(suite, "port_get_set_port", test_port_get_set_port); CU_add_test(suite, "port_get_set_con", test_port_get_set_con); CU_add_test(suite, "port_create", test_port_create); CU_add_test(suite, "port_clone", test_port_clone); CU_add_test(suite, "port_query", test_port_query); CU_add_test(suite, "port_exists", test_port_exists); CU_add_test(suite, "port_count", test_port_count); CU_add_test(suite, "port_iterate", test_port_iterate); CU_add_test(suite, "port_list", test_port_list); CU_add_test(suite, "port_modify_del_local", test_port_modify_del_local); CU_add_test(suite, "port_query_local", test_port_query_local); CU_add_test(suite, "port_exists_local", test_port_exists_local); CU_add_test(suite, "port_count_local", test_port_count_local); CU_add_test(suite, "port_iterate_local", test_port_iterate_local); CU_add_test(suite, "port_list_local", test_port_list_local); CU_add_test(suite, "port_validate_local", test_port_validate_local); return 0; } /* Helpers */ static semanage_port_t *get_port_nth(int idx) { int res; semanage_port_t **records; semanage_port_t *port; unsigned int count; if (idx == I_NULL) return NULL; res = semanage_port_list(sh, &records, &count); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_FATAL(count >= (unsigned int) idx + 1); port = records[idx]; for (unsigned int i = 0; i < count; i++) if (i != (unsigned int) idx) semanage_port_free(records[i]); free(records); return port; } static semanage_port_key_t *get_port_key_nth(int idx) { semanage_port_key_t *key; semanage_port_t *port; int res; if (idx == I_NULL) return NULL; port = get_port_nth(idx); res = semanage_port_key_extract(sh, port, &key); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); /* cleanup */ semanage_port_free(port); return key; } static void add_local_port(int port_idx) { semanage_port_t *port; semanage_port_key_t *key = NULL; CU_ASSERT_FATAL(port_idx != I_NULL); port = get_port_nth(port_idx); CU_ASSERT_FATAL(semanage_port_key_extract(sh, port, &key) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); CU_ASSERT_FATAL(semanage_port_modify_local(sh, key, port) >= 0); /* cleanup */ semanage_port_key_free(key); semanage_port_free(port); } static void delete_local_port(int port_idx) { semanage_port_key_t *key = NULL; CU_ASSERT_FATAL(port_idx != I_NULL); key = get_port_key_nth(port_idx); CU_ASSERT_FATAL(semanage_port_del_local(sh, key) >= 0); semanage_port_key_free(key); } /* Function semanage_port_compare */ static void helper_port_compare(int idx1, int idx2) { semanage_port_t *port = NULL; semanage_port_key_t *key = NULL; int res = 42; /* setup */ setup_handle(SH_CONNECT); port = get_port_nth(idx1); key = get_port_key_nth(idx2); /* test */ res = semanage_port_compare(port, key); if (idx1 == idx2) { CU_ASSERT(res == 0); } else { CU_ASSERT(res != 0); } /* cleanup */ semanage_port_free(port); semanage_port_key_free(key); cleanup_handle(SH_CONNECT); } static void test_port_compare(void) { helper_port_compare(I_FIRST, I_FIRST); helper_port_compare(I_FIRST, I_SECOND); helper_port_compare(I_SECOND, I_FIRST); helper_port_compare(I_SECOND, I_SECOND); } /* Function semanage_port_compare2 */ static void helper_port_compare2(int idx1, int idx2) { semanage_port_t *port1 = NULL; semanage_port_t *port2 = NULL; int res = 42; /* setup */ setup_handle(SH_CONNECT); port1 = get_port_nth(idx1); port2 = get_port_nth(idx2); /* test */ res = semanage_port_compare2(port1, port2); if (idx1 == idx2) { CU_ASSERT(res == 0); } else { CU_ASSERT(res != 0); } /* cleanup */ semanage_port_free(port1); semanage_port_free(port2); cleanup_handle(SH_CONNECT); } static void test_port_compare2(void) { helper_port_compare2(I_FIRST, I_FIRST); helper_port_compare2(I_FIRST, I_SECOND); helper_port_compare2(I_SECOND, I_FIRST); helper_port_compare2(I_SECOND, I_SECOND); } /* Function semanage_port_create */ static void test_port_key_create(void) { semanage_port_key_t *key = NULL; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_port_key_create(sh, 1000, 1200, 0, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* cleanup */ semanage_port_key_free(key); cleanup_handle(SH_CONNECT); } /* Function semanage_port_extract */ static void test_port_key_extract(void) { semanage_port_t *port = NULL; semanage_port_key_t *key = NULL; /* setup */ setup_handle(SH_CONNECT); port = get_port_nth(I_FIRST); /* test */ CU_ASSERT(semanage_port_key_extract(sh, port, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* cleanup */ semanage_port_free(port); semanage_port_key_free(key); cleanup_handle(SH_CONNECT); } /* Function semanage_port_get_proto, semanage_port_set_proto */ static void helper_port_get_set_proto(int idx) { semanage_port_t *port = NULL; /* setup */ setup_handle(SH_CONNECT); port = get_port_nth(idx); /* test */ semanage_port_set_proto(port, 0); CU_ASSERT(semanage_port_get_proto(port) == 0); semanage_port_set_proto(port, 1); CU_ASSERT(semanage_port_get_proto(port) == 1); /* cleanup */ semanage_port_free(port); cleanup_handle(SH_CONNECT); } static void test_port_get_set_proto(void) { helper_port_get_set_proto(I_FIRST); helper_port_get_set_proto(I_SECOND); } /* Function semanage_port_get_proto_str */ static void test_port_get_proto_str(void) { const char *str = NULL; str = semanage_port_get_proto_str(-1); CU_ASSERT_STRING_EQUAL(str, "???"); str = semanage_port_get_proto_str(0); CU_ASSERT_STRING_EQUAL(str, "udp"); str = semanage_port_get_proto_str(1); CU_ASSERT_STRING_EQUAL(str, "tcp"); str = semanage_port_get_proto_str(2); CU_ASSERT_STRING_EQUAL(str, "dccp"); str = semanage_port_get_proto_str(3); CU_ASSERT_STRING_EQUAL(str, "sctp"); str = semanage_port_get_proto_str(4); CU_ASSERT_STRING_EQUAL(str, "???"); } /* Function semanage_port_get_low, semanage_port_get_high, */ /* semanage_port_set_port, semanage_port_set_range */ static void test_port_get_set_port(void) { semanage_port_t *port = NULL; /* setup */ setup_handle(SH_CONNECT); port = get_port_nth(I_FIRST); /* test */ semanage_port_set_port(port, 1000); CU_ASSERT(semanage_port_get_low(port) == 1000); CU_ASSERT(semanage_port_get_high(port) == 1000); semanage_port_set_range(port, 1000, 1200); CU_ASSERT(semanage_port_get_low(port) == 1000); CU_ASSERT(semanage_port_get_high(port) == 1200); /* cleanup */ semanage_port_free(port); cleanup_handle(SH_CONNECT); } /* Function semanage_port_get_con, semanage_port_set_con */ static void test_port_get_set_con(void) { semanage_port_t *port = NULL; semanage_port_t *port_tmp = NULL; semanage_context_t *con1 = NULL; semanage_context_t *con2 = NULL; /* setup */ setup_handle(SH_CONNECT); port = get_port_nth(I_FIRST); port_tmp = get_port_nth(I_SECOND); con1 = semanage_port_get_con(port_tmp); /* test */ CU_ASSERT(semanage_port_set_con(sh, port, con1) >= 0); con2 = semanage_port_get_con(port); CU_ASSERT_CONTEXT_EQUAL(con1, con2); /* cleanup */ semanage_port_free(port); semanage_port_free(port_tmp); cleanup_handle(SH_CONNECT); } /* Function semanage_port_create */ static void test_port_create(void) { semanage_port_t *port = NULL; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_port_create(sh, &port) >= 0); CU_ASSERT(semanage_port_get_low(port) == 0); CU_ASSERT(semanage_port_get_high(port) == 0); CU_ASSERT(semanage_port_get_con(port) == NULL); CU_ASSERT(semanage_port_get_proto(port) == 0); /* cleanup */ semanage_port_free(port); cleanup_handle(SH_CONNECT); } /* Function semanage_port_clone */ static void test_port_clone(void) { semanage_port_t *port = NULL; semanage_port_t *port_clone = NULL; semanage_context_t *con = NULL; semanage_context_t *con2 = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_port_create(sh, &port) >= 0); semanage_port_set_range(port, 1000, 1200); semanage_port_set_proto(port, 1); semanage_context_from_string(sh, "user_u:role_r:type_t:s0", &con); semanage_port_set_con(sh, port, con); /* test */ CU_ASSERT(semanage_port_clone(sh, port, &port_clone) >= 0); CU_ASSERT(semanage_port_get_low(port_clone) == 1000); CU_ASSERT(semanage_port_get_high(port_clone) == 1200); CU_ASSERT(semanage_port_get_proto(port_clone) == 1); con2 = semanage_port_get_con(port_clone); CU_ASSERT_CONTEXT_EQUAL(con, con2); /* cleanup */ semanage_context_free(con); semanage_port_free(port); semanage_port_free(port_clone); cleanup_handle(SH_CONNECT); } /* Function semanage_port_query */ static void test_port_query(void) { semanage_port_t *port = NULL; semanage_port_t *port_exp = NULL; semanage_port_key_t *key = NULL; semanage_context_t *con = NULL; semanage_context_t *con_exp = NULL; /* setup */ setup_handle(SH_CONNECT); key = get_port_key_nth(I_FIRST); port_exp = get_port_nth(I_FIRST); /* test */ CU_ASSERT(semanage_port_query(sh, key, &port) >= 0); CU_ASSERT(semanage_port_get_low(port) == semanage_port_get_low(port_exp)); CU_ASSERT(semanage_port_get_high(port) == semanage_port_get_high(port_exp)); CU_ASSERT(semanage_port_get_proto(port) == semanage_port_get_proto(port_exp)); con = semanage_port_get_con(port); con_exp = semanage_port_get_con(port_exp); CU_ASSERT_CONTEXT_EQUAL(con, con_exp); /* cleanup */ semanage_port_key_free(key); semanage_port_free(port); semanage_port_free(port_exp); cleanup_handle(SH_CONNECT); } /* Function semanage_port_exists */ static void test_port_exists(void) { semanage_port_key_t *key1 = NULL; semanage_port_key_t *key2 = NULL; int resp = 42; /* setup */ setup_handle(SH_CONNECT); key1 = get_port_key_nth(I_FIRST); CU_ASSERT(semanage_port_key_create(sh, 123, 456, 0, &key2) >= 0); /* test */ CU_ASSERT(semanage_port_exists(sh, key1, &resp) >= 0); CU_ASSERT(resp); CU_ASSERT(semanage_port_exists(sh, key2, &resp) >= 0); CU_ASSERT(!resp); /* cleanup */ semanage_port_key_free(key1); semanage_port_key_free(key2); cleanup_handle(SH_CONNECT); } /* Function semanage_port_count */ static void test_port_count(void) { unsigned int count = 42; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_port_count(sh, &count) >= 0); CU_ASSERT(count == PORT_COUNT); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_port_iterate */ static unsigned int counter_port_iterate = 0; static int handler_port_iterate(__attribute__((unused)) const semanage_port_t *record, __attribute__((unused)) void *varg) { counter_port_iterate++; return 0; } static void test_port_iterate(void) { /* setup */ setup_handle(SH_CONNECT); /* test */ semanage_port_iterate(sh, handler_port_iterate, NULL); CU_ASSERT(counter_port_iterate == PORT_COUNT); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_port_list */ static void test_port_list(void) { semanage_port_t **records = NULL; unsigned int count = 42; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_port_list(sh, &records, &count) >= 0); CU_ASSERT(count == PORT_COUNT); for (unsigned int i = 0; i < count; i++) CU_ASSERT_PTR_NOT_NULL(records[i]); /* cleanup */ for (unsigned int i = 0; i < count; i++) semanage_port_free(records[i]); free(records); cleanup_handle(SH_CONNECT); } /* Function semanage_port_modify_local, semanage_port_del_local */ static void test_port_modify_del_local(void) { semanage_port_t *port; semanage_port_t *port_local; semanage_port_key_t *key = NULL; semanage_context_t *con = NULL; semanage_context_t *con_local = NULL; /* setup */ setup_handle(SH_TRANS); port = get_port_nth(I_FIRST); semanage_context_from_string(sh, "user_u:role_r:type_t:s0", &con); semanage_port_set_con(sh, port, con); CU_ASSERT(semanage_port_key_extract(sh, port, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* test */ CU_ASSERT(semanage_port_modify_local(sh, key, port) >= 0); CU_ASSERT(semanage_port_query_local(sh, key, &port_local) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(port_local); con_local = semanage_port_get_con(port_local); CU_ASSERT_CONTEXT_EQUAL(con, con_local); semanage_port_free(port_local); CU_ASSERT(semanage_port_del_local(sh, key) >= 0); CU_ASSERT(semanage_port_query_local(sh, key, &port_local) < 0); /* cleanup */ semanage_context_free(con); semanage_port_key_free(key); semanage_port_free(port); cleanup_handle(SH_TRANS); } /* Function semanage_port_query_local */ static void test_port_query_local(void) { semanage_port_t *port = NULL; semanage_port_t *port_exp = NULL; semanage_port_key_t *key = NULL; semanage_context_t *con = NULL; semanage_context_t *con_exp = NULL; /* setup */ setup_handle(SH_TRANS); add_local_port(I_FIRST); key = get_port_key_nth(I_FIRST); port_exp = get_port_nth(I_FIRST); /* test */ CU_ASSERT(semanage_port_query_local(sh, key, &port) >= 0); CU_ASSERT(semanage_port_get_low(port) == semanage_port_get_low(port_exp)); CU_ASSERT(semanage_port_get_high(port) == semanage_port_get_high(port_exp)); CU_ASSERT(semanage_port_get_proto(port) == semanage_port_get_proto(port_exp)); con = semanage_port_get_con(port); con_exp = semanage_port_get_con(port_exp); CU_ASSERT_CONTEXT_EQUAL(con, con_exp); /* cleanup */ delete_local_port(I_FIRST); semanage_port_key_free(key); semanage_port_free(port); semanage_port_free(port_exp); cleanup_handle(SH_TRANS); } /* Function semanage_port_exists_local */ static void test_port_exists_local(void) { semanage_port_key_t *key1 = NULL; semanage_port_key_t *key2 = NULL; int resp = 42; /* setup */ setup_handle(SH_TRANS); add_local_port(I_FIRST); key1 = get_port_key_nth(I_FIRST); key2 = get_port_key_nth(I_SECOND); /* test */ CU_ASSERT(semanage_port_exists_local(sh, key1, &resp) >= 0); CU_ASSERT(resp); CU_ASSERT(semanage_port_exists_local(sh, key2, &resp) >= 0); CU_ASSERT(!resp); /* cleanup */ delete_local_port(I_FIRST); semanage_port_key_free(key1); semanage_port_key_free(key2); cleanup_handle(SH_TRANS); } /* Function semanage_port_count_local */ static void test_port_count_local(void) { unsigned int count = 42; /* setup */ setup_handle(SH_TRANS); /* test */ CU_ASSERT(semanage_port_count_local(sh, &count) >= 0); CU_ASSERT(count == 0); add_local_port(I_FIRST); CU_ASSERT(semanage_port_count_local(sh, &count) >= 0); CU_ASSERT(count == 1); add_local_port(I_SECOND); CU_ASSERT(semanage_port_count_local(sh, &count) >= 0); CU_ASSERT(count == 2); delete_local_port(I_SECOND); CU_ASSERT(semanage_port_count_local(sh, &count) >= 0); CU_ASSERT(count == 1); delete_local_port(I_FIRST); CU_ASSERT(semanage_port_count_local(sh, &count) >= 0); CU_ASSERT(count == 0); /* cleanup */ cleanup_handle(SH_TRANS); } /* Function semanage_port_iterate_local */ static unsigned int counter_port_iterate_local = 0; static int handler_port_iterate_local(__attribute__((unused)) const semanage_port_t *record, __attribute__((unused)) void *varg) { counter_port_iterate_local++; return 0; } static void test_port_iterate_local(void) { /* setup */ setup_handle(SH_TRANS); add_local_port(I_FIRST); add_local_port(I_SECOND); add_local_port(I_THIRD); /* test */ semanage_port_iterate_local(sh, handler_port_iterate_local, NULL); CU_ASSERT(counter_port_iterate_local == 3); /* cleanup */ delete_local_port(I_FIRST); delete_local_port(I_SECOND); delete_local_port(I_THIRD); cleanup_handle(SH_TRANS); } /* Function semanage_port_list_local */ static void test_port_list_local(void) { semanage_port_t **records = NULL; unsigned int count = 42; /* setup */ setup_handle(SH_TRANS); add_local_port(I_FIRST); add_local_port(I_SECOND); add_local_port(I_THIRD); /* test */ CU_ASSERT(semanage_port_list_local(sh, &records, &count) >= 0); CU_ASSERT(count == 3); for (unsigned int i = 0; i < count; i++) CU_ASSERT_PTR_NOT_NULL(records[i]); /* cleanup */ for (unsigned int i = 0; i < count; i++) semanage_port_free(records[i]); free(records); delete_local_port(I_FIRST); delete_local_port(I_SECOND); delete_local_port(I_THIRD); cleanup_handle(SH_TRANS); } /* Internal function semanage_port_validate_local */ static void helper_port_validate_local_noport(void) { semanage_port_key_t *key = NULL; int resp = 42; /* setup */ setup_handle(SH_TRANS); add_local_port(I_FIRST); helper_commit(); key = get_port_key_nth(I_FIRST); CU_ASSERT(semanage_port_exists_local(sh, key, &resp) >= 0); CU_ASSERT(resp); /* test */ helper_begin_transaction(); delete_local_port(I_FIRST); helper_commit(); /* cleanup */ semanage_port_key_free(key); helper_begin_transaction(); delete_local_port(I_FIRST); cleanup_handle(SH_TRANS); } static void helper_port_validate_local_oneport(void) { /* setup */ setup_handle(SH_TRANS); add_local_port(I_FIRST); /* test */ helper_commit(); /* cleanup */ helper_begin_transaction(); delete_local_port(I_FIRST); cleanup_handle(SH_TRANS); } static void helper_port_validate_local_twoports(void) { semanage_port_key_t *key1 = NULL; semanage_port_key_t *key2 = NULL; semanage_port_t *port1 = NULL; semanage_port_t *port2 = NULL; semanage_context_t *con1 = NULL; semanage_context_t *con2 = NULL; /* setup */ setup_handle(SH_TRANS); CU_ASSERT(semanage_port_key_create(sh, 101, 200, 0, &key1) >= 0); CU_ASSERT(semanage_port_key_create(sh, 201, 300, 0, &key2) >= 0); CU_ASSERT(semanage_port_create(sh, &port1) >= 0); CU_ASSERT(semanage_port_create(sh, &port2) >= 0); semanage_port_set_range(port1, 101, 200); semanage_port_set_range(port2, 201, 300); semanage_port_set_proto(port1, 0); semanage_port_set_proto(port2, 0); CU_ASSERT(semanage_context_from_string(sh, "system_u:object_r:user_home_t:s0", &con1) >= 0); CU_ASSERT(semanage_context_from_string(sh, "system_u:object_r:user_tmp_t:s0", &con2) >= 0); semanage_port_set_con(sh, port1, con1); semanage_port_set_con(sh, port2, con2); CU_ASSERT(semanage_port_modify_local(sh, key1, port1) >= 0); CU_ASSERT(semanage_port_modify_local(sh, key2, port2) >= 0); /* test */ helper_commit(); /* cleanup */ helper_begin_transaction(); CU_ASSERT(semanage_port_del_local(sh, key1) >= 0); CU_ASSERT(semanage_port_del_local(sh, key2) >= 0); semanage_context_free(con2); semanage_context_free(con1); semanage_port_key_free(key1); semanage_port_key_free(key2); semanage_port_free(port1); semanage_port_free(port2); cleanup_handle(SH_TRANS); } static void test_port_validate_local(void) { helper_port_validate_local_noport(); helper_port_validate_local_oneport(); helper_port_validate_local_twoports(); } libsemanage-3.8.1/tests/test_port.cil000066400000000000000000000014661476211737200176710ustar00rootroot00000000000000(typeattribute cil_gen_require) (roleattribute cil_gen_require) (handleunknown allow) (mls true) (policycap open_perms) (sid security) (sidorder (security)) (sensitivity s0) (sensitivityorder (s0)) (user system_u) (userrole system_u object_r) (userlevel system_u (s0)) (userrange system_u ((s0) (s0))) (role object_r) (roletype object_r first_port_t) (roletype object_r second_port_t) (roletype object_r third_port_t) (type first_port_t) (type second_port_t) (type third_port_t) (sidcontext security (system_u object_r first_port_t ((s0) (s0)))) (class file (open)) (classorder (file)) (allow first_port_t self (file (open))) (portcon tcp 80 (system_u object_r first_port_t ((s0) (s0)))) (portcon udp (1 1023) (system_u object_r second_port_t ((s0) (s0)))) (portcon tcp 12345 (system_u object_r third_port_t ((s0) (s0)))) libsemanage-3.8.1/tests/test_port.h000066400000000000000000000017561476211737200173530ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 __TEST_PORT_H__ #define __TEST_PORT_H__ #include int port_test_init(void); int port_test_cleanup(void); int port_add_tests(CU_pSuite suite); #endif libsemanage-3.8.1/tests/test_semanage_store.c000066400000000000000000000221221476211737200213440ustar00rootroot00000000000000/* 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 static const char *const rootpath = "./test-policy"; static const char *const polpath = "./test-policy/store/"; static const char *const readlockpath = "./test-policy/store/semanage.read.LOCK"; static const char *const translockpath = "./test-policy/store/semanage.trans.LOCK"; static const char *const actpath = "./test-policy/store/active"; static const char *const modpath = "./test-policy/store/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(rootpath, S_IRUSR | S_IWUSR | S_IXUSR); if (err != 0) return -1; err = mkdir(polpath, 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; /* use our own policy store */ free(sh->conf->store_path); sh->conf->store_path = strdup("store"); /* initialize paths */ err = semanage_check_init(sh, rootpath); 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(polpath); if (err != 0) return -1; err = rmdir(rootpath); 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(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(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 polpath */ err = chmod(polpath, 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-3.8.1/tests/test_semanage_store.h000066400000000000000000000023421476211737200213530ustar00rootroot00000000000000/* 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-3.8.1/tests/test_user.c000066400000000000000000000426131476211737200173350ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 "utilities.h" #include "test_user.h" #define USER_COUNT 3 /* user_record.h */ static void test_user_compare(void); static void test_user_compare2(void); static void test_user_key_create(void); static void test_user_key_extract(void); static void test_user_get_set_name(void); static void test_user_get_set_prefix(void); static void test_user_get_set_mlslevel(void); static void test_user_get_set_mlsrange(void); static void test_user_roles(void); static void test_user_create(void); static void test_user_clone(void); /* users_policy.h */ static void test_user_query(void); static void test_user_exists(void); static void test_user_count(void); static void test_user_iterate(void); static void test_user_list(void); /* users_local.h */ static void test_user_modify_del_query_local(void); static void test_user_exists_local(void); static void test_user_count_local(void); static void test_user_iterate_local(void); static void test_user_list_local(void); int user_test_init(void) { if (create_test_store() < 0) { fprintf(stderr, "Could not create test store\n"); return 1; } if (write_test_policy_from_file("test_user.policy") < 0) { fprintf(stderr, "Could not write test policy\n"); return 1; } return 0; } int user_test_cleanup(void) { if (destroy_test_store() < 0) { fprintf(stderr, "Could not destroy test store\n"); return 1; } return 0; } int user_add_tests(CU_pSuite suite) { CU_add_test(suite, "user_compare", test_user_compare); CU_add_test(suite, "user_compare2", test_user_compare2); CU_add_test(suite, "user_key_create", test_user_key_create); CU_add_test(suite, "user_key_extract", test_user_key_extract); CU_add_test(suite, "user_get_set_name", test_user_get_set_name); CU_add_test(suite, "user_get_set_prefix", test_user_get_set_prefix); CU_add_test(suite, "user_get_set_mlslevel", test_user_get_set_mlslevel); CU_add_test(suite, "user_get_set_mlsrange", test_user_get_set_mlsrange); CU_add_test(suite, "user_roles", test_user_roles); CU_add_test(suite, "user_create", test_user_create); CU_add_test(suite, "user_clone", test_user_clone); CU_add_test(suite, "user_query", test_user_query); CU_add_test(suite, "user_exists", test_user_exists); CU_add_test(suite, "user_count", test_user_count); CU_add_test(suite, "user_iterate", test_user_iterate); CU_add_test(suite, "user_list", test_user_list); CU_add_test(suite, "user_modify_del_query_local", test_user_modify_del_query_local); CU_add_test(suite, "user_exists_local", test_user_exists_local); CU_add_test(suite, "user_count_local", test_user_count_local); CU_add_test(suite, "user_iterate_local", test_user_iterate_local); CU_add_test(suite, "user_list_local", test_user_list_local); return 0; } /* Helpers */ static semanage_user_t *get_user_nth(int idx) { int res; semanage_user_t **records; semanage_user_t *user; unsigned int count; if (idx == I_NULL) return NULL; res = semanage_user_list(sh, &records, &count); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_FATAL(count >= (unsigned int) idx + 1); user = records[idx]; for (unsigned int i = 0; i < count; i++) if (i != (unsigned int) idx) semanage_user_free(records[i]); free(records); return user; } static semanage_user_key_t *get_user_key_nth(int idx) { semanage_user_key_t *key; semanage_user_t *user; int res; if (idx == I_NULL) return NULL; user = get_user_nth(idx); res = semanage_user_key_extract(sh, user, &key); CU_ASSERT_FATAL(res >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); semanage_user_free(user); return key; } static void add_local_user(int user_idx) { semanage_user_t *user; semanage_user_key_t *key = NULL; CU_ASSERT_FATAL(user_idx != I_NULL); user = get_user_nth(user_idx); CU_ASSERT_FATAL(semanage_user_key_extract(sh, user, &key) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(key); CU_ASSERT_FATAL(semanage_user_modify_local(sh, key, user) >= 0); semanage_user_key_free(key); semanage_user_free(user); } static void delete_local_user(int user_idx) { semanage_user_key_t *key = NULL; CU_ASSERT_FATAL(user_idx != I_NULL); key = get_user_key_nth(user_idx); CU_ASSERT_FATAL(semanage_user_del_local(sh, key) >= 0); semanage_user_key_free(key); } /* Function semanage_user_compare */ static void test_user_compare(void) { semanage_user_t *user = NULL; semanage_user_key_t *key1 = NULL; semanage_user_key_t *key2 = NULL; int res = 42; /* setup */ setup_handle(SH_CONNECT); user = get_user_nth(I_FIRST); key1 = get_user_key_nth(I_FIRST); key2 = get_user_key_nth(I_SECOND); /* test */ res = semanage_user_compare(user, key1); CU_ASSERT(res == 0); res = semanage_user_compare(user, key2); CU_ASSERT(res != 0); /* cleanup */ semanage_user_free(user); semanage_user_key_free(key1); semanage_user_key_free(key2); cleanup_handle(SH_CONNECT); } /* Function semanage_user_compare2 */ static void test_user_compare2(void) { semanage_user_t *user1 = NULL; semanage_user_t *user2 = NULL; semanage_user_t *user3 = NULL; int res = 42; /* setup */ setup_handle(SH_CONNECT); user1 = get_user_nth(I_FIRST); user2 = get_user_nth(I_FIRST); user3 = get_user_nth(I_SECOND); /* test */ res = semanage_user_compare2(user1, user2); CU_ASSERT(res == 0); res = semanage_user_compare2(user1, user3); CU_ASSERT(res != 0); /* cleanup */ semanage_user_free(user1); semanage_user_free(user2); semanage_user_free(user3); cleanup_handle(SH_CONNECT); } /* Function semanage_user_key_create */ static void test_user_key_create(void) { semanage_user_key_t *key = NULL; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_user_key_create(sh, "asdf", &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* cleanup */ semanage_user_key_free(key); cleanup_handle(SH_CONNECT); } /* Function semanage_user_key_extract */ static void test_user_key_extract(void) { semanage_user_t *user = NULL; semanage_user_key_t *key = NULL; /* setup */ setup_handle(SH_CONNECT); user = get_user_nth(I_FIRST); /* test */ CU_ASSERT(semanage_user_key_extract(sh, user, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* cleanup */ semanage_user_free(user); semanage_user_key_free(key); cleanup_handle(SH_CONNECT); } /* Function semanage_user_get_name, semanage_user_set_name */ static void test_user_get_set_name(void) { semanage_user_t *user = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_user_create(sh, &user) >= 0); /* test */ CU_ASSERT(semanage_user_set_name(sh, user, "user_u") == 0); CU_ASSERT_STRING_EQUAL(semanage_user_get_name(user), "user_u"); /* cleanup */ semanage_user_free(user); cleanup_handle(SH_CONNECT); } /* Function semanage_user_get_prefix, semanage_user_set_prefix */ static void test_user_get_set_prefix(void) { semanage_user_t *user = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_user_create(sh, &user) >= 0); /* test */ CU_ASSERT(semanage_user_set_prefix(sh, user, "user") == 0); CU_ASSERT_STRING_EQUAL(semanage_user_get_prefix(user), "user"); /* cleanup */ semanage_user_free(user); cleanup_handle(SH_CONNECT); } /* Function semanage_user_get_mlslevel, semanage_user_set_mlslevel */ static void test_user_get_set_mlslevel(void) { semanage_user_t *user = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_user_create(sh, &user) >= 0); /* test */ CU_ASSERT(semanage_user_set_mlslevel(sh, user, "s0") == 0); CU_ASSERT_STRING_EQUAL(semanage_user_get_mlslevel(user), "s0"); /* cleanup */ semanage_user_free(user); cleanup_handle(SH_CONNECT); } /* Function semanage_user_get_mlsrange, semanage_user_set_mlsrange */ static void test_user_get_set_mlsrange(void) { semanage_user_t *user = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_user_create(sh, &user) >= 0); /* test */ CU_ASSERT(semanage_user_set_mlsrange(sh, user, "s0-s15") == 0); CU_ASSERT_STRING_EQUAL(semanage_user_get_mlsrange(user), "s0-s15"); /* cleanup */ semanage_user_free(user); cleanup_handle(SH_CONNECT); } /* Function semanage_user_get_num_roles, semanage_user_add_role, * semanage_user_del_role, semanage_user_has_role, semanage_user_get_roles * semanage_user_set_roles */ static void test_user_roles(void) { semanage_user_t *user = NULL; const char **roles_arr = NULL; unsigned int num_roles = 42; const char *new_roles_arr[] = { "new_role_r", "new_my_role_r" }; unsigned int new_num_roles = 2; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_user_create(sh, &user) >= 0); /* test */ CU_ASSERT(semanage_user_get_num_roles(user) == 0); CU_ASSERT(semanage_user_add_role(sh, user, "role_r") == 0); CU_ASSERT(semanage_user_get_num_roles(user) == 1); CU_ASSERT(semanage_user_has_role(user, "role_r")); CU_ASSERT(!semanage_user_has_role(user, "my_role_r")); CU_ASSERT(semanage_user_add_role(sh, user, "my_role_r") == 0); CU_ASSERT(semanage_user_get_num_roles(user) == 2); CU_ASSERT(semanage_user_get_roles(sh, user, &roles_arr, &num_roles) >= 0); CU_ASSERT(num_roles == 2); CU_ASSERT_STRING_EQUAL(roles_arr[0], "role_r"); CU_ASSERT_STRING_EQUAL(roles_arr[1], "my_role_r"); CU_ASSERT(semanage_user_set_roles(sh, user, new_roles_arr, new_num_roles) >= 0); CU_ASSERT(semanage_user_has_role(user, "new_role_r")); CU_ASSERT(semanage_user_has_role(user, "new_my_role_r")); CU_ASSERT(!semanage_user_has_role(user, "role_r")); CU_ASSERT(!semanage_user_has_role(user, "my_role_r")); semanage_user_del_role(user, "new_my_role_r"); CU_ASSERT(semanage_user_get_num_roles(user) == 1); semanage_user_del_role(user, "new_role_r"); CU_ASSERT(semanage_user_get_num_roles(user) == 0); /* cleanup */ free(roles_arr); semanage_user_free(user); cleanup_handle(SH_CONNECT); } /* Function semanage_user_create */ static void test_user_create(void) { semanage_user_t *user = NULL; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_user_create(sh, &user) >= 0); CU_ASSERT(semanage_user_set_name(sh, user, "user_u") >= 0); CU_ASSERT(semanage_user_set_prefix(sh, user, "user") >= 0); CU_ASSERT(semanage_user_set_mlslevel(sh, user, "s0") >= 0); CU_ASSERT(semanage_user_set_mlsrange(sh, user, "s0-s15") >= 0); /* cleanup */ semanage_user_free(user); cleanup_handle(SH_CONNECT); } /* Function semanage_user_clone */ static void test_user_clone(void) { semanage_user_t *user = NULL; semanage_user_t *user_clone = NULL; /* setup */ setup_handle(SH_CONNECT); CU_ASSERT(semanage_user_create(sh, &user) >= 0); CU_ASSERT(semanage_user_set_name(sh, user, "user_u") >= 0); CU_ASSERT(semanage_user_set_prefix(sh, user, "user") >= 0); CU_ASSERT(semanage_user_set_mlslevel(sh, user, "s0") >= 0); CU_ASSERT(semanage_user_set_mlsrange(sh, user, "s0-s15") >= 0); /* test */ CU_ASSERT(semanage_user_clone(sh, user, &user_clone) >= 0); CU_ASSERT_STRING_EQUAL(semanage_user_get_name(user), "user_u"); CU_ASSERT_STRING_EQUAL(semanage_user_get_prefix(user), "user"); CU_ASSERT_STRING_EQUAL(semanage_user_get_mlslevel(user), "s0"); CU_ASSERT_STRING_EQUAL(semanage_user_get_mlsrange(user), "s0-s15"); /* cleanup */ semanage_user_free(user); semanage_user_free(user_clone); cleanup_handle(SH_CONNECT); } /* Function semanage_user_query */ static void test_user_query(void) { semanage_user_t *user = NULL; semanage_user_key_t *key = NULL; /* setup */ setup_handle(SH_CONNECT); key = get_user_key_nth(I_FIRST); /* test */ CU_ASSERT(semanage_user_query(sh, key, &user) >= 0); /* TODO: test values */ CU_ASSERT_PTR_NOT_NULL(user); /* cleanup */ semanage_user_key_free(key); semanage_user_free(user); cleanup_handle(SH_CONNECT); } /* Function semanage_user_exists */ static void test_user_exists(void) { semanage_user_key_t *key1 = NULL; semanage_user_key_t *key2 = NULL; int resp = 42; /* setup */ setup_handle(SH_CONNECT); key1 = get_user_key_nth(I_FIRST); CU_ASSERT(semanage_user_key_create(sh, "asdf", &key2) >= 0); /* test */ CU_ASSERT(semanage_user_exists(sh, key1, &resp) >= 0); CU_ASSERT(resp); CU_ASSERT(semanage_user_exists(sh, key2, &resp) >= 0); CU_ASSERT(!resp); /* cleanup */ semanage_user_key_free(key1); semanage_user_key_free(key2); cleanup_handle(SH_CONNECT); } /* Function semanage_user_count */ static void test_user_count(void) { unsigned int count = 42; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_user_count(sh, &count) >= 0); CU_ASSERT(count == USER_COUNT); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_user_iterate */ static unsigned int counter_user_iterate = 0; static int handler_user_iterate(__attribute__((unused)) const semanage_user_t *record, __attribute__((unused)) void *varg) { counter_user_iterate++; return 0; } static void test_user_iterate(void) { /* setup */ setup_handle(SH_CONNECT); /* test */ semanage_user_iterate(sh, handler_user_iterate, NULL); CU_ASSERT(counter_user_iterate == USER_COUNT); /* cleanup */ cleanup_handle(SH_CONNECT); } /* Function semanage_user_list */ static void test_user_list(void) { semanage_user_t **records = NULL; unsigned int count = 42; /* setup */ setup_handle(SH_CONNECT); /* test */ CU_ASSERT(semanage_user_list(sh, &records, &count) >= 0); CU_ASSERT(count == USER_COUNT); /* TODO: check real values */ for (unsigned int i = 0; i < count; i++) CU_ASSERT_PTR_NOT_NULL(records[i]); /* cleanup */ for (unsigned int i = 0; i < count; i++) semanage_user_free(records[i]); free(records); cleanup_handle(SH_CONNECT); } /* Function semanage_user_modify_local, semanage_user_del_local, * semanage_user_query_local */ static void test_user_modify_del_query_local(void) { semanage_user_t *user; semanage_user_t *user_local; semanage_user_key_t *key = NULL; /* setup */ setup_handle(SH_TRANS); user = get_user_nth(I_FIRST); CU_ASSERT(semanage_user_key_extract(sh, user, &key) >= 0); CU_ASSERT_PTR_NOT_NULL(key); /* test */ CU_ASSERT(semanage_user_modify_local(sh, key, user) >= 0); /* write changes to file */ helper_commit(); helper_begin_transaction(); CU_ASSERT(semanage_user_query_local(sh, key, &user_local) >= 0); CU_ASSERT_PTR_NOT_NULL_FATAL(user_local); semanage_user_free(user_local); CU_ASSERT(semanage_user_del_local(sh, key) >= 0); CU_ASSERT(semanage_user_query_local(sh, key, &user_local) < 0); /* cleanup */ semanage_user_key_free(key); semanage_user_free(user); cleanup_handle(SH_TRANS); } /* Function semanage_user_exists_local */ static void test_user_exists_local(void) { semanage_user_t *user = NULL; semanage_user_key_t *key1 = NULL; semanage_user_key_t *key2 = NULL; int resp = 42; /* setup */ setup_handle(SH_TRANS); add_local_user(I_FIRST); key1 = get_user_key_nth(I_FIRST); CU_ASSERT(semanage_user_key_create(sh, "asdf", &key2) >= 0); CU_ASSERT_PTR_NOT_NULL(key2); /* test */ CU_ASSERT(semanage_user_exists_local(sh, key1, &resp) >= 0); CU_ASSERT(resp); CU_ASSERT(semanage_user_exists_local(sh, key2, &resp) >= 0); CU_ASSERT(!resp); /* cleanup */ CU_ASSERT(semanage_user_del_local(sh, key1) >= 0); semanage_user_free(user); semanage_user_key_free(key1); semanage_user_key_free(key2); cleanup_handle(SH_TRANS); } /* Function semanage_user_count_local */ static void test_user_count_local(void) { unsigned int count = 42; /* setup */ setup_handle(SH_TRANS); add_local_user(I_FIRST); add_local_user(I_SECOND); add_local_user(I_THIRD); /* test */ CU_ASSERT(semanage_user_count_local(sh, &count) >= 0); CU_ASSERT(count == 3); /* cleanup */ delete_local_user(I_FIRST); delete_local_user(I_SECOND); delete_local_user(I_THIRD); cleanup_handle(SH_TRANS); } /* Function semanage_user_iterate_local */ static unsigned int counter_user_iterate_local = 0; static int handler_user_iterate_local(__attribute__((unused)) const semanage_user_t *record, __attribute__((unused)) void *varg) { counter_user_iterate_local++; return 0; } static void test_user_iterate_local(void) { /* setup */ setup_handle(SH_TRANS); add_local_user(I_FIRST); add_local_user(I_SECOND); add_local_user(I_THIRD); /* test */ semanage_user_iterate_local(sh, handler_user_iterate_local, NULL); CU_ASSERT(counter_user_iterate_local == 3); /* cleanup */ delete_local_user(I_FIRST); delete_local_user(I_SECOND); delete_local_user(I_THIRD); cleanup_handle(SH_TRANS); } /* Function semanage_user_list_local */ static void test_user_list_local(void) { semanage_user_t **records = NULL; unsigned int count = 42; /* setup */ setup_handle(SH_TRANS); add_local_user(I_FIRST); add_local_user(I_SECOND); add_local_user(I_THIRD); /* test */ CU_ASSERT(semanage_user_list_local(sh, &records, &count) >= 0); CU_ASSERT(count == 3); for (unsigned int i = 0; i < count; i++) CU_ASSERT_PTR_NOT_NULL(records[i]); /* cleanup */ for (unsigned int i = 0; i < count; i++) semanage_user_free(records[i]); free(records); delete_local_user(I_FIRST); delete_local_user(I_SECOND); delete_local_user(I_THIRD); cleanup_handle(SH_TRANS); } libsemanage-3.8.1/tests/test_user.cil000066400000000000000000000012721476211737200176560ustar00rootroot00000000000000(typeattribute cil_gen_require) (roleattribute cil_gen_require) (handleunknown allow) (mls true) (policycap network_peer_controls) (policycap open_perms) (sid security) (sidorder (security)) (sensitivity s0) (sensitivityorder (s0)) (user first_u) (user second_u) (user third_u) (userrole first_u object_r) (userlevel first_u (s0)) (userlevel second_u (s0)) (userlevel third_u (s0)) (userrange first_u ((s0) (s0))) (userrange second_u ((s0) (s0))) (userrange third_u ((s0) (s0))) (role object_r) (roletype object_r test_t) (type test_t) (sidcontext security (first_u object_r test_t ((s0) (s0)))) (class test_class (test_perm)) (classorder (test_class)) (allow test_t self (test_class (test_perm))) libsemanage-3.8.1/tests/test_user.h000066400000000000000000000017561476211737200173450ustar00rootroot00000000000000/* * Authors: Jan Zarsky * * Copyright (C) 2019 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 __TEST_USER_H__ #define __TEST_USER_H__ #include int user_test_init(void); int user_test_cleanup(void); int user_add_tests(CU_pSuite suite); #endif libsemanage-3.8.1/tests/test_utilities.c000066400000000000000000000212471476211737200203720ustar00rootroot00000000000000/* 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 #include "utilities.h" #include "test_utilities.h" static void test_semanage_is_prefix(void); static void test_semanage_split_on_space(void); static void test_semanage_split(void); static void test_semanage_list(void); static void test_semanage_str_count(void); static void test_semanage_rtrim(void); static void test_semanage_str_replace(void); static void test_semanage_findval(void); static void test_slurp_file_filter(void); static char fname[] = { 'T', 'E', 'S', 'T', '_', 'T', 'E', 'M', 'P', '_', 'X', 'X', 'X', 'X', 'X', 'X', '\0' }; 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_str_replace", test_semanage_str_replace)) { 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(); } static void test_semanage_is_prefix(void) { const char *str = "some string"; const char *pre = "some"; const 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)); } static 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"); return; } temp = semanage_split_on_space(str); CU_ASSERT_PTR_NOT_NULL_FATAL(temp); CU_ASSERT_STRING_EQUAL(temp, "bar baz"); free(str); str = temp; temp = semanage_split_on_space(str); CU_ASSERT_PTR_NOT_NULL_FATAL(temp); CU_ASSERT_STRING_EQUAL(temp, "baz"); free(str); str = temp; temp = semanage_split_on_space(str); CU_ASSERT_PTR_NOT_NULL_FATAL(temp); CU_ASSERT_STRING_EQUAL(temp, ""); free(str); free(temp); } static 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_PTR_NOT_NULL_FATAL(temp); CU_ASSERT_STRING_EQUAL(temp, "foo2 foo:bar:"); free(str); str = temp; temp = semanage_split(str, ""); CU_ASSERT_PTR_NOT_NULL_FATAL(temp); CU_ASSERT_STRING_EQUAL(temp, "foo:bar:"); free(str); str = temp; temp = semanage_split(str, ":"); CU_ASSERT_PTR_NOT_NULL_FATAL(temp); CU_ASSERT_STRING_EQUAL(temp, "bar:"); free(str); str = temp; temp = semanage_split(str, ":"); CU_ASSERT_PTR_NOT_NULL_FATAL(temp); CU_ASSERT_STRING_EQUAL(temp, ""); free(str); free(temp); } static 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); } static void test_semanage_str_count(void) { const 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); } static 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"); free(str); } static void test_semanage_str_replace(void) { const char *test_str = "Hello, I am %{USERNAME} and my id is %{USERID}"; char *str1, *str2; str1 = semanage_str_replace("%{USERNAME}", "root", test_str, 0); CU_ASSERT_STRING_EQUAL(str1, "Hello, I am root and my id is %{USERID}"); str2 = semanage_str_replace("%{USERID}", "0", str1, 1); CU_ASSERT_STRING_EQUAL(str2, "Hello, I am root and my id is 0"); free(str1); free(str2); str1 = semanage_str_replace(":(", ";)", "Test :( :) ! :(:(:))(:(", 0); CU_ASSERT_STRING_EQUAL(str1, "Test ;) :) ! ;);):))(;)"); free(str1); str1 = semanage_str_replace(":(", ";)", "Test :( :) ! :(:(:))(:(", 3); CU_ASSERT_STRING_EQUAL(str1, "Test ;) :) ! ;);):))(:("); free(str1); str1 = semanage_str_replace("", "empty search string", "test", 0); CU_ASSERT_EQUAL(str1, NULL); str1 = semanage_str_replace("a", "", "abracadabra", 0); CU_ASSERT_STRING_EQUAL(str1, "brcdbr"); free(str1); } static 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_PTR_NOT_NULL_FATAL(tok); CU_ASSERT_STRING_EQUAL(tok, ""); free(tok); rewind(fptr); tok = semanage_findval(fname, "one", ""); CU_ASSERT_PTR_NOT_NULL_FATAL(tok); CU_ASSERT_STRING_EQUAL(tok, ""); free(tok); rewind(fptr); tok = semanage_findval(fname, "sigma", "="); CU_ASSERT_PTR_NOT_NULL_FATAL(tok); CU_ASSERT_STRING_EQUAL(tok, "foo"); free(tok); } static int PREDICATE(const char *str) { return semanage_is_prefix(str, "#"); } static 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-3.8.1/tests/test_utilities.h000066400000000000000000000002401476211737200203650ustar00rootroot00000000000000#include int semanage_utilities_test_init(void); int semanage_utilities_test_cleanup(void); int semanage_utilities_add_tests(CU_pSuite suite); libsemanage-3.8.1/tests/utilities.c000066400000000000000000000127151476211737200173330ustar00rootroot00000000000000/* Authors: Christopher Ashworth * * Copyright (C) 2006 Tresys Technology, LLC * Copyright (C) 2019 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 */ /* The purpose of this file is to provide some functions commonly needed * by our unit tests. */ #include "utilities.h" static int test_store_enabled = 0; semanage_handle_t *sh = NULL; /* Silence any error output caused by our tests * by using this dummy function to catch messages. */ void test_msg_handler(__attribute__((unused)) void *varg, __attribute__((unused)) semanage_handle_t *handle, __attribute__((unused)) const char *fmt, ...) { } int create_test_store(void) { FILE *fptr; if (mkdir("test-policy", 0700) < 0) return -1; if (mkdir("test-policy/store", 0700) < 0) return -1; if (mkdir("test-policy/store/active", 0700) < 0) return -1; if (mkdir("test-policy/store/active/modules", 0700) < 0) return -1; if (mkdir("test-policy/etc", 0700) < 0) return -1; if (mkdir("test-policy/etc/selinux", 0700) < 0) return -1; fptr = fopen("test-policy/etc/selinux/semanage.conf", "w+"); if (!fptr) return -1; fclose(fptr); enable_test_store(); return 0; } void disable_test_store(void) { test_store_enabled = 0; } void enable_test_store(void) { test_store_enabled = 1; } static int write_test_policy(char *data, size_t data_len) { FILE *fptr = fopen("test-policy/store/active/policy.kern", "wb+"); if (!fptr) { perror("fopen"); return -1; } if (fwrite(data, data_len, 1, fptr) != 1) { perror("fwrite"); fclose(fptr); return -1; } fclose(fptr); return 0; } int write_test_policy_from_file(const char *filename) { char *buf = NULL; size_t len = 0; FILE *fptr = fopen(filename, "rb"); int rc; if (!fptr) { perror("fopen"); return -1; } fseek(fptr, 0, SEEK_END); len = ftell(fptr); fseek(fptr, 0, SEEK_SET); buf = (char *) malloc(len); if (!buf) { perror("malloc"); fclose(fptr); return -1; } fread(buf, len, 1, fptr); fclose(fptr); rc = write_test_policy(buf, len); free(buf); return rc; } int write_test_policy_src(unsigned char *data, unsigned int data_len) { if (mkdir("test-policy/store/active/modules/100", 0700) < 0) return -1; if (mkdir("test-policy/store/active/modules/100/base", 0700) < 0) return -1; FILE *fptr = fopen("test-policy/store/active/modules/100/base/cil", "w+"); if (!fptr) { perror("fopen"); return -1; } if (fwrite(data, data_len, 1, fptr) != 1) { perror("fwrite"); fclose(fptr); return -1; } fclose(fptr); fptr = fopen("test-policy/store/active/modules/100/base/lang_ext", "w+"); if (!fptr) { perror("fopen"); return -1; } if (fwrite("cil", sizeof("cil"), 1, fptr) != 1) { perror("fwrite"); fclose(fptr); return -1; } fclose(fptr); return 0; } int destroy_test_store(void) { FTS *ftsp = NULL; FTSENT *curr = NULL; int ret = 0; disable_test_store(); char *files[] = { (char *) "test-policy", NULL }; ftsp = fts_open(files, FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV, NULL); if (!ftsp) return -1; while ((curr = fts_read(ftsp))) switch (curr->fts_info) { case FTS_DP: case FTS_F: case FTS_SL: case FTS_SLNONE: case FTS_DEFAULT: if (remove(curr->fts_accpath) < 0) ret = -1; default: break; } fts_close(ftsp); return ret; } void helper_handle_create(void) { if (test_store_enabled) semanage_set_root("test-policy"); sh = semanage_handle_create(); CU_ASSERT_PTR_NOT_NULL(sh); semanage_msg_set_callback(sh, test_msg_handler, NULL); if (test_store_enabled) { semanage_set_create_store(sh, 1); semanage_set_reload(sh, 0); semanage_set_store_root(sh, ""); semanage_select_store(sh, "store", SEMANAGE_CON_DIRECT); } } void helper_handle_destroy(void) { semanage_handle_destroy(sh); } void helper_connect(void) { CU_ASSERT(semanage_connect(sh) >= 0); } void helper_disconnect(void) { CU_ASSERT(semanage_disconnect(sh) >= 0); } void helper_begin_transaction(void) { CU_ASSERT(semanage_begin_transaction(sh) >= 0); } void helper_commit(void) { CU_ASSERT(semanage_commit(sh) >= 0); } void setup_handle(level_t level) { if (level >= SH_NULL) sh = NULL; if (level >= SH_HANDLE) helper_handle_create(); if (level >= SH_CONNECT) helper_connect(); if (level >= SH_TRANS) helper_begin_transaction(); } void cleanup_handle(level_t level) { if (level >= SH_TRANS) helper_commit(); if (level >= SH_CONNECT) helper_disconnect(); if (level >= SH_HANDLE) helper_handle_destroy(); if (level >= SH_NULL) sh = NULL; } void setup_handle_invalid_store(level_t level) { CU_ASSERT(level >= SH_HANDLE); helper_handle_create(); semanage_select_store(sh, "", SEMANAGE_CON_INVALID); if (level >= SH_CONNECT) helper_connect(); if (level >= SH_TRANS) helper_begin_transaction(); } libsemanage-3.8.1/tests/utilities.h000066400000000000000000000055061476211737200173400ustar00rootroot00000000000000/* Authors: Christopher Ashworth * * Copyright (C) 2006 Tresys Technology, LLC * Copyright (C) 2019 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 __UTILITIES_H__ #define __UTILITIES_H__ #include #include #include #include #include #include #include #include #include "semanage/semanage.h" #define CU_ASSERT_CONTEXT_EQUAL(CON1,CON2) \ do { \ char *str__; \ char *str2__; \ CU_ASSERT(semanage_context_to_string(sh, CON1, &str__) >= 0); \ CU_ASSERT(semanage_context_to_string(sh, CON2, &str2__) >= 0); \ CU_ASSERT_STRING_EQUAL(str__, str2__); \ free(str2__); \ free(str__); \ } while (0) /* Override CU_*_FATAL() in order to help static analyzers by really asserting that an assertion holds */ #ifdef __CHECKER__ #undef CU_ASSERT_FATAL #define CU_ASSERT_FATAL(value) do { \ int value_ = (value); \ CU_ASSERT(value_); \ assert(value_); \ } while (0) #undef CU_FAIL_FATAL #define CU_FAIL_FATAL(msg) do { \ CU_FAIL(msg); \ assert(0); \ } while (0) #undef CU_ASSERT_PTR_NOT_NULL_FATAL #define CU_ASSERT_PTR_NOT_NULL_FATAL(value) do { \ const void *value_ = (value); \ CU_ASSERT_PTR_NOT_NULL(value_); \ assert(value_ != NULL); \ } while (0) #endif /* __CHECKER__ */ #define I_NULL (-1) #define I_FIRST 0 #define I_SECOND 1 #define I_THIRD 2 extern semanage_handle_t *sh; typedef enum { SH_NULL, SH_HANDLE, SH_CONNECT, SH_TRANS } level_t; void test_msg_handler(void *varg, semanage_handle_t *handle, const char *fmt, ...); void setup_handle(level_t level); void cleanup_handle(level_t level); void setup_handle_invalid_store(level_t level); void helper_handle_create(void); void helper_handle_destroy(void); void helper_connect(void); void helper_disconnect(void); void helper_begin_transaction(void); void helper_commit(void); int create_test_store(void); int write_test_policy_from_file(const char *filename); int write_test_policy_src(unsigned char *data, unsigned int data_len); int destroy_test_store(void); void enable_test_store(void); void disable_test_store(void); #endif libsemanage-3.8.1/utils/000077500000000000000000000000001476211737200151445ustar00rootroot00000000000000libsemanage-3.8.1/utils/Makefile000066400000000000000000000004401476211737200166020ustar00rootroot00000000000000# Installation directories. PREFIX ?= /usr LIBEXECDIR ?= $(PREFIX)/libexec SELINUXEXECDIR ?= $(LIBEXECDIR)/selinux/ all: install: all -mkdir -p $(DESTDIR)$(SELINUXEXECDIR) install -m 755 semanage_migrate_store $(DESTDIR)$(SELINUXEXECDIR) clean: distclean: clean indent: relabel: libsemanage-3.8.1/utils/semanage_migrate_store000077500000000000000000000217731476211737200216100ustar00rootroot00000000000000#!/usr/bin/python3 -E from __future__ import print_function import os import errno import shutil import sys from optparse import OptionParser try: import selinux import semanage except ImportError: print("You must install libselinux-python and libsemanage-python before running this tool", file=sys.stderr) exit(1) def copy_file(src, dst): if DEBUG: print("copying %s to %s" % (src, dst)) try: shutil.copy(src, dst) except OSError as the_err: (err, strerr) = the_err.args print("Could not copy %s to %s, %s" % (src, dst, strerr), file=sys.stderr) exit(1) def create_dir(dst, mode): if DEBUG: print("Making directory %s" % dst) try: os.makedirs(dst, mode) except OSError as the_err: (err, stderr) = the_err.args if err == errno.EEXIST: pass else: print("Error creating %s" % dst, file=sys.stderr) exit(1) def create_file(dst): if DEBUG: print("Making file %s" % dst) try: open(dst, 'a').close() except OSError as the_err: (err, stderr) = the_err.args print("Error creating %s" % dst, file=sys.stderr) exit(1) def copy_module(store, name, base): if DEBUG: print("Install module %s" % name) (file, ext) = os.path.splitext(name) if ext != ".pp": # Stray non-pp file in modules directory, skip print("warning: %s has invalid extension, skipping" % name, file=sys.stderr) return try: if base: root = oldstore_path(store) else: root = oldmodules_path(store) bottomdir = bottomdir_path(store) os.mkdir("%s/%s" % (bottomdir, file)) copy_file(os.path.join(root, name), "%s/%s/hll" % (bottomdir, file)) # This is the ext file that will eventually be used to choose a compiler efile = open("%s/%s/lang_ext" % (bottomdir, file), "w+", 0o600) efile.write("pp") efile.close() except (IOError, OSError): print("Error installing module %s" % name, file=sys.stderr) exit(1) def disable_module(file, name, disabledmodules): if DEBUG: print("Disabling %s" % name) (disabledname, disabledext) = os.path.splitext(file) create_file("%s/%s" % (disabledmodules, disabledname)) def migrate_store(store): oldstore = oldstore_path(store) oldmodules = oldmodules_path(store) disabledmodules = disabledmodules_path(store) newstore = newstore_path(store) newmodules = newmodules_path(store) bottomdir = bottomdir_path(store) print("Migrating from %s to %s" % (oldstore, newstore)) # Build up new directory structure create_dir("%s/%s" % (newroot_path(), store), 0o755) create_dir(newstore, 0o700) create_dir(newmodules, 0o700) create_dir(bottomdir, 0o700) create_dir(disabledmodules, 0o700) # Special case for base since it was in a different location copy_module(store, "base.pp", 1) # Dir structure built, start copying files for root, dirs, files in os.walk(oldstore): if root == oldstore: # This is the top level directory, need to move for name in files: # Check to see if it is in TOPPATHS and copy if so if name in TOPPATHS: if name == "seusers": newname = "seusers.local" else: newname = name copy_file(os.path.join(root, name), os.path.join(newstore, newname)) elif root == oldmodules: # This should be the modules directory for name in files: (file, ext) = os.path.splitext(name) if name == "base.pp": print("Error installing module %s, name conflicts with base" % name, file=sys.stderr) exit(1) elif ext == ".disabled": disable_module(file, name, disabledmodules) else: copy_module(store, name, 0) def rebuild_policy(): # Ok, the modules are loaded, lets try to rebuild the policy print("Attempting to rebuild policy from %s" % newroot_path()) curstore = selinux.selinux_getpolicytype()[1] handle = semanage.semanage_handle_create() if not handle: print("Could not create semanage handle", file=sys.stderr) exit(1) semanage.semanage_select_store(handle, curstore, semanage.SEMANAGE_CON_DIRECT) if not semanage.semanage_is_managed(handle): semanage.semanage_handle_destroy(handle) print("SELinux policy is not managed or store cannot be accessed.", file=sys.stderr) exit(1) rc = semanage.semanage_access_check(handle) if rc < semanage.SEMANAGE_CAN_WRITE: semanage.semanage_handle_destroy(handle) print("Cannot write to policy store.", file=sys.stderr) exit(1) rc = semanage.semanage_connect(handle) if rc < 0: semanage.semanage_handle_destroy(handle) print("Could not establish semanage connection", file=sys.stderr) exit(1) semanage.semanage_set_rebuild(handle, 1) rc = semanage.semanage_begin_transaction(handle) if rc < 0: semanage.semanage_handle_destroy(handle) print("Could not begin transaction", file=sys.stderr) exit(1) rc = semanage.semanage_commit(handle) if rc < 0: print("Could not commit transaction", file=sys.stderr) semanage.semanage_handle_destroy(handle) def oldroot_path(): return "%s/etc/selinux" % ROOT def oldstore_path(store): return "%s/%s/modules/active" % (oldroot_path(), store) def oldmodules_path(store): return "%s/modules" % oldstore_path(store) def disabledmodules_path(store): return "%s/disabled" % newmodules_path(store) def newroot_path(): return "%s%s" % (ROOT, PATH) def newstore_path(store): return "%s/%s/active" % (newroot_path(), store) def newmodules_path(store): return "%s/modules" % newstore_path(store) def bottomdir_path(store): return "%s/%s" % (newmodules_path(store), PRIORITY) if __name__ == "__main__": parser = OptionParser() parser.add_option("-p", "--priority", dest="priority", default="100", help="Set priority of modules in new store (default: 100)") parser.add_option("-s", "--store", dest="store", default=None, help="Store to read from and write to") parser.add_option("-d", "--debug", dest="debug", action="store_true", default=False, help="Output debug information") parser.add_option("-c", "--clean", dest="clean", action="store_true", default=False, help="Clean old modules directory after migrate (default: no)") parser.add_option("-n", "--norebuild", dest="norebuild", action="store_true", default=False, help="Disable rebuilding policy after migration (default: no)") parser.add_option("-P", "--path", dest="path", help="Set path for the policy store (default: /var/lib/selinux)") parser.add_option("-r", "--root", dest="root", help="Set an alternative root for the migration (default: /)") (options, args) = parser.parse_args() DEBUG = options.debug PRIORITY = options.priority TYPE = options.store CLEAN = options.clean NOREBUILD = options.norebuild PATH = options.path if PATH is None: PATH = "/var/lib/selinux" ROOT = options.root if ROOT is None: ROOT = "" # List of paths that go in the active 'root' TOPPATHS = [ "commit_num", "ports.local", "interfaces.local", "nodes.local", "booleans.local", "file_contexts.local", "seusers", "users.local", "users_extra", "users_extra.local", "disable_dontaudit", "preserve_tunables", "policy.kern", "file_contexts", "homedir_template", "pkeys.local", "ibendports.local"] create_dir(newroot_path(), 0o755) stores = None if TYPE is not None: stores = [TYPE] else: stores = os.listdir(oldroot_path()) # find stores in oldroot and migrate them to newroot if necessary for store in stores: if not os.path.isdir(oldmodules_path(store)): # already migrated or not an selinux store continue if os.path.isdir(newstore_path(store)): # store has already been migrated, but old modules dir still exits print("warning: Policy type %s has already been migrated, but modules still exist in the old store. Skipping store." % store, file=sys.stderr) continue migrate_store(store) if CLEAN is True: def remove_error(function, path, execinfo): print("warning: Unable to remove old store modules directory %s. Cleaning failed." % oldmodules_path(store), file=sys.stderr) shutil.rmtree(oldmodules_path(store), onerror=remove_error) if NOREBUILD is False: rebuild_policy()