pax_global_header00006660000000000000000000000064141342746730014525gustar00rootroot0000000000000052 comment=7f600c40bc18d8180993edcd54daf45124736776 policycoreutils-3.3/000077500000000000000000000000001413427467300146235ustar00rootroot00000000000000policycoreutils-3.3/.gitignore000066400000000000000000000003371413427467300166160ustar00rootroot00000000000000load_policy/load_policy newrole/newrole run_init/open_init_pty run_init/run_init secon/secon semodule/semodule sestatus/sestatus setfiles/restorecon setfiles/restorecon_xattr setfiles/setfiles setsebool/setsebool hll/pp/pp policycoreutils-3.3/.tx/000077500000000000000000000000001413427467300153345ustar00rootroot00000000000000policycoreutils-3.3/.tx/config000066400000000000000000000002471413427467300165270ustar00rootroot00000000000000[main] host = https://www.transifex.com [policycoreutils.policycoreutils] file_filter = po/.po source_file = po/policycoreutils.pot source_lang = en type = PO policycoreutils-3.3/COPYING000066400000000000000000000431311413427467300156600ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. policycoreutils-3.3/Makefile000066400000000000000000000003411413427467300162610ustar00rootroot00000000000000SUBDIRS = setfiles load_policy newrole run_init secon sestatus semodule setsebool scripts po man hll all install relabel clean indent: @for subdir in $(SUBDIRS); do \ (cd $$subdir && $(MAKE) $@) || exit 1; \ done test: policycoreutils-3.3/VERSION000066400000000000000000000000041413427467300156650ustar00rootroot000000000000003.3 policycoreutils-3.3/hll/000077500000000000000000000000001413427467300154025ustar00rootroot00000000000000policycoreutils-3.3/hll/Makefile000066400000000000000000000002111413427467300170340ustar00rootroot00000000000000SUBDIRS = pp all install relabel clean indent: @for subdir in $(SUBDIRS); do \ (cd $$subdir && $(MAKE) $@) || exit 1; \ done test: policycoreutils-3.3/hll/pp/000077500000000000000000000000001413427467300160215ustar00rootroot00000000000000policycoreutils-3.3/hll/pp/Makefile000066400000000000000000000010061413427467300174560ustar00rootroot00000000000000# Installation directories. PREFIX ?= /usr LIBEXECDIR ?= $(PREFIX)/libexec HLLDIR ?= $(LIBEXECDIR)/selinux/hll CFLAGS ?= -Werror -Wall -W override LDLIBS += -lsepol PP_SRCS = $(sort $(wildcard *.c)) PP_OBJS = $(patsubst %.c,%.o,$(PP_SRCS)) all: pp pp: $(PP_OBJS) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) %.o: %.c $(CC) $(CFLAGS) -c -o $@ $^ install: all -mkdir -p $(DESTDIR)$(HLLDIR) install -m 755 pp $(DESTDIR)$(HLLDIR) relabel: clean: -rm -f pp $(PP_OBJS) indent: ../../scripts/Lindent $(wildcard *.[ch]) policycoreutils-3.3/hll/pp/pp.c000066400000000000000000000076331413427467300166150ustar00rootroot00000000000000/* * Copyright (C) 2014 Tresys Technology, LLC * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include char *progname; __attribute__ ((format(printf, 1, 2))) static void log_err(const char *fmt, ...) { va_list argptr; va_start(argptr, fmt); if (vfprintf(stderr, fmt, argptr) < 0) { _exit(EXIT_FAILURE); } va_end(argptr); if (fprintf(stderr, "\n") < 0) { _exit(EXIT_FAILURE); } } static __attribute__((__noreturn__)) void usage(int err) { fprintf(stderr, "Usage: %s [OPTIONS] [IN_FILE [OUT_FILE]]\n", progname); fprintf(stderr, "\n"); fprintf(stderr, "Read an SELinux policy package (.pp) and output the equivalent CIL.\n"); fprintf(stderr, "If IN_FILE is not provided or is -, read SELinux policy package from\n"); fprintf(stderr, "standard input. If OUT_FILE is not provided or is -, output CIL to\n"); fprintf(stderr, "standard output.\n"); fprintf(stderr, "\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -h, --help print this message and exit\n"); exit(err); } int main(int argc, char **argv) { int rc = -1; int opt; static struct option long_opts[] = { { "help", 0, NULL, 'h' }, { NULL, 0, NULL, 0 } }; struct sepol_module_package *mod_pkg = NULL; const char *ifile = NULL; const char *ofile = NULL; FILE *in = NULL; FILE *out = NULL; // ignore sigpipe so we can check the return code of write, and potentially // return a more helpful error message signal(SIGPIPE, SIG_IGN); progname = basename(argv[0]); while ((opt = getopt_long(argc, argv, "h", long_opts, NULL)) != -1) { switch (opt) { case 'h': usage(0); case '?': default: usage(1); } } if (argc >= optind + 1 && strcmp(argv[1], "-") != 0) { ifile = argv[1]; in = fopen(ifile, "rb"); if (in == NULL) { log_err("Failed to open %s: %s", ifile, strerror(errno)); rc = -1; goto exit; } } else { ifile = "stdin"; in = stdin; } if (argc >= optind + 2 && strcmp(argv[2], "-") != 0) { ofile = argv[2]; out = fopen(ofile, "w"); if (out == NULL) { log_err("Failed to open %s: %s", ofile, strerror(errno)); rc = -1; goto exit; } } else { out = stdout; } if (argc >= optind + 3) { log_err("Too many arguments"); usage(1); } rc = sepol_ppfile_to_module_package(in, &mod_pkg); if (rc != 0) { goto exit; } fclose(in); in = NULL; if (ofile) { char *mod_name = mod_pkg->policy->p.name; char *cil_path = strdup(ofile); if (cil_path == NULL) { log_err("No memory available for strdup\n"); rc = -1; goto exit; } char *cil_name = basename(cil_path); char *separator = strrchr(cil_name, '.'); if (separator) { *separator = '\0'; } if (mod_name && strcmp(mod_name, cil_name) != 0) { fprintf(stderr, "Warning: SELinux userspace will refer to the module from %s as %s rather than %s\n", ifile, mod_name, cil_name); } free(cil_path); } rc = sepol_module_package_to_cil(out, mod_pkg); if (rc != 0) { goto exit; } exit: if (in != NULL) { fclose(in); } if (out != NULL) { fclose(out); } sepol_module_package_free(mod_pkg); return rc; } policycoreutils-3.3/load_policy/000077500000000000000000000000001413427467300171215ustar00rootroot00000000000000policycoreutils-3.3/load_policy/Makefile000066400000000000000000000017741413427467300205720ustar00rootroot00000000000000# Installation directories. LINGUAS ?= ru PREFIX ?= /usr SBINDIR ?= $(PREFIX)/sbin MANDIR ?= $(PREFIX)/share/man LOCALEDIR ?= $(DESTDIR)$(PREFIX)/share/locale CFLAGS ?= -Werror -Wall -W override CFLAGS += $(LDFLAGS) -DUSE_NLS -DLOCALEDIR="\"$(LOCALEDIR)\"" -DPACKAGE="\"policycoreutils\"" override LDLIBS += -lsepol -lselinux TARGETS=$(patsubst %.c,%,$(sort $(wildcard *.c))) all: $(TARGETS) install: all -mkdir -p $(DESTDIR)$(SBINDIR) install -m 755 $(TARGETS) $(DESTDIR)$(SBINDIR) test -d $(DESTDIR)$(MANDIR)/man8 || install -m 755 -d $(DESTDIR)$(MANDIR)/man8 install -m 644 load_policy.8 $(DESTDIR)$(MANDIR)/man8/ for lang in $(LINGUAS) ; do \ if [ -e $${lang} ] ; then \ test -d $(DESTDIR)$(MANDIR)/$${lang}/man8 || install -m 755 -d $(DESTDIR)$(MANDIR)/$${lang}/man8 ; \ install -m 644 $${lang}/*.8 $(DESTDIR)$(MANDIR)/$${lang}/man8/ ; \ fi ; \ done clean: -rm -f $(TARGETS) *.o indent: ../../scripts/Lindent $(wildcard *.[ch]) relabel: /sbin/restorecon $(DESTDIR)$(SBINDIR)/load_policy policycoreutils-3.3/load_policy/load_policy.8000066400000000000000000000016261413427467300215150ustar00rootroot00000000000000.TH LOAD_POLICY "8" "May 2003" "Security Enhanced Linux" NSA .SH NAME load_policy \- load a new SELinux policy into the kernel .SH SYNOPSIS .B load_policy [\-qi] .br .SH DESCRIPTION .PP load_policy loads the installed policy file into the kernel. The existing policy boolean values are automatically preserved across policy reloads rather than being reset to the default values in the policy file. .SH "OPTIONS" .TP .B \-q suppress warning messages. .TP .B \-i initial policy load. Only use this if this is the first time policy is being loaded since boot (usually called from initramfs). .SH "EXIT STATUS" .TP .B 0 Success .TP .B 1 Invalid option .TP .B 2 Policy load failed .TP .B 3 Initial policy load failed and enforcing mode requested .SH SEE ALSO .BR booleans (8) .SH AUTHORS .nf This manual page was written by Dan Walsh . The program was written by Stephen Smalley . policycoreutils-3.3/load_policy/load_policy.c000066400000000000000000000040601413427467300215630ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #ifdef USE_NLS #include /* for setlocale() */ #include /* for gettext() */ #define _(msgid) gettext (msgid) #else #define _(msgid) (msgid) #endif #ifndef PACKAGE #define PACKAGE "policycoreutils" /* the name of this package lang translation */ #endif static __attribute__((__noreturn__)) void usage(const char *progname) { fprintf(stderr, _("usage: %s [-qi]\n"), progname); exit(1); } int main(int argc, char **argv) { int ret, opt, quiet = 0, nargs, init=0, enforce=0; #ifdef USE_NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif while ((opt = getopt(argc, argv, "bqi")) > 0) { switch (opt) { case 'b': fprintf(stderr, "%s: Warning! The -b option is no longer supported, booleans are always preserved across reloads. Continuing...\n", argv[0]); break; case 'q': quiet = 1; sepol_debug(0); break; case 'i': init = 1; break; default: usage(argv[0]); } } nargs = argc - optind; if (nargs > 2) usage(argv[0]); if (nargs >= 1 && !quiet) { fprintf(stderr, "%s: Warning! Policy file argument (%s) is no longer supported, installed policy is always loaded. Continuing...\n", argv[0], argv[optind++]); } if (nargs == 2 && ! quiet) { fprintf(stderr, "%s: Warning! Boolean file argument (%s) is no longer supported, installed booleans file is always used. Continuing...\n", argv[0], argv[optind++]); } if (init) { ret = selinux_init_load_policy(&enforce); if (ret != 0 ) { if (enforce > 0) { /* SELinux in enforcing mode but load_policy failed */ fprintf(stderr, _("%s: Can't load policy and enforcing mode requested: %s\n"), argv[0], strerror(errno)); exit(3); } } } else { ret = selinux_mkload_policy(0); } if (ret < 0) { fprintf(stderr, _("%s: Can't load policy: %s\n"), argv[0], strerror(errno)); exit(2); } exit(0); } policycoreutils-3.3/load_policy/ru/000077500000000000000000000000001413427467300175475ustar00rootroot00000000000000policycoreutils-3.3/load_policy/ru/load_policy.8000066400000000000000000000033521413427467300221410ustar00rootroot00000000000000.TH LOAD_POLICY "8" "Май 2003" "Security Enhanced Linux" NSA .SH ИМЯ load_policy \- загрузить новую политику SELinux в ядро .SH ОБЗОР .B load_policy [\-qi] .br .SH ОПИСАНИЕ .PP load_policy загружает установленный файл политики в ядро. Существующие значения логических переключателей политики автоматически сохраняются при перезагрузках политики, а не сбрасываются на установленные в файле политики значения по умолчанию. .SH "ПАРАМЕТРЫ" .TP .B \-q Отменить предупредительные сообщения. .TP .B \-i Начальная загрузка политики. Следует использовать, только если политика загружается впервые с момента запуска (обычно вызывается из initramfs). .SH "СОСТОЯНИЕ ВЫХОДА" .TP .B 0 Успешно .TP .B 1 Недействительный параметр .TP .B 2 Не удалось загрузить политику .TP .B 3 Не удалось выполнить начальную загрузку политики, запрошен принудительный режим .SH СМОТРИТЕ ТАКЖЕ .BR booleans (8) .SH АВТОРЫ .nf Эта страница руководства была написана Dan Walsh . Программа была написана Stephen Smalley . Перевод на русский язык выполнила Герасименко Олеся . policycoreutils-3.3/man/000077500000000000000000000000001413427467300153765ustar00rootroot00000000000000policycoreutils-3.3/man/Makefile000066400000000000000000000006611413427467300170410ustar00rootroot00000000000000# Installation directories. LINGUAS ?= ru PREFIX ?= /usr MANDIR ?= $(PREFIX)/share/man MAN5DIR ?= $(MANDIR)/man5 all: clean: install: all mkdir -p $(DESTDIR)$(MAN5DIR) install -m 644 man5/*.5 $(DESTDIR)$(MAN5DIR) for lang in $(LINGUAS) ; do \ if [ -e $${lang}/man5 ] ; then \ mkdir -p $(DESTDIR)$(MANDIR)/$${lang}/man5 ; \ install -m 644 $${lang}/man5/*.5 $(DESTDIR)$(MANDIR)/$${lang}/man5 ; \ fi ; \ done relabel: policycoreutils-3.3/man/man5/000077500000000000000000000000001413427467300162365ustar00rootroot00000000000000policycoreutils-3.3/man/man5/selinux_config.5000066400000000000000000000120431413427467300213400ustar00rootroot00000000000000.TH "selinux_config" "5" "18 Nov 2011" "Security Enhanced Linux" "SELinux configuration file" .SH "NAME" config \- The SELinux sub-system configuration file. .SH "DESCRIPTION" The SELinux \fIconfig\fR file controls the state of SELinux regarding: .RS .IP "1." 4 The policy enforcement status \- \fIenforcing\fR, \fIpermissive\fR or \fIdisabled\fR. .IP "2." 4 The policy name or type that forms a path to the policy to be loaded and its supporting configuration files. .IP "3." 4 How SELinux-aware login applications should behave if no valid SELinux users are configured. .IP "4." 4 Whether the system is to be relabeled or not. .RE The entries controlling these functions are described in the \fBFILE FORMAT\fR section. .sp The fully qualified path name of the SELinux configuration file is \fI/etc/selinux/config\fR. .sp If the \fIconfig\fR file is missing or corrupt, then no SELinux policy is loaded (i.e. SELinux is disabled). .sp The \fBsestatus\fR (8) command and the libselinux function \fBselinux_path\fR (3) will return the location of the \fIconfig\fR file. .SH "FILE FORMAT" The \fIconfig\fR file supports the following parameters: .sp .RS \fBSELINUX = \fIenforcing\fR | \fIpermissive\fR | \fIdisabled\fR .br \fBSELINUXTYPE = \fIpolicy_name\fR .br \fBREQUIREUSERS = \fI0\fR | \fI1\fR .br \fBAUTORELABEL = \fI0\fR | \fI1\fR .RE .sp Where: .br .B SELINUX .RS This entry can contain one of three values: .RS .IP \fIenforcing\fR 4 SELinux security policy is enforced. .IP \fIpermissive\fR 4 SELinux security policy is not enforced but logs the warnings (i.e. the action is allowed to proceed). .IP \fIdisabled\fR No SELinux policy is loaded. This option was used to disable SELinux completely, which is now deprecated. Use the \fBselinux=0\fR kernel boot option instead (see \fBselinux\fR(8)). .RE .sp The entry can be determined using the \fBsestatus\fR(8) command or \fBselinux_getenforcemode\fR(3). .RE .sp .B SELINUXTYPE .RS The \fIpolicy_name\fR entry is used to identify the policy type, and becomes the directory name of where the policy and its configuration files are located. .sp The entry can be determined using the \fBsestatus\fR(8) command or \fBselinux_getpolicytype\fR(3). .sp The \fIpolicy_name\fR is relative to a path that is defined within the SELinux subsystem that can be retrieved by using \fBselinux_path\fR(3). An example entry retrieved by \fBselinux_path\fR(3) is: .br .RS .I /etc/selinux/ .RE .sp The \fIpolicy_name\fR is then appended to this and becomes the 'policy root' location that can be retrieved by \fBselinux_policy_root_path\fR(3). An example entry retrieved is: .RS .I /etc/selinux/targeted .RE .sp The actual binary policy is located relative to this directory and also has a policy name pre-allocated. This information can be retrieved using \fBselinux_binary_policy_path\fR(3). An example entry retrieved by \fBselinux_binary_policy_path\fR(3) is: .br .RS .I /etc/selinux/targeted/policy/policy .RE .sp The binary policy name has by convention the SELinux policy version that it supports appended to it. The maximum policy version supported by the kernel can be determined using the \fBsestatus\fR(8) command or \fBsecurity_policyvers\fR(3). An example binary policy file with the version is: .br .RS .I /etc/selinux/targeted/policy/policy.24 .RE .RE .sp .B REQUIRESEUSERS .RS This optional entry can be used to fail a login if there is no matching or default entry in the .BR seusers "(5) file or if the " seusers " file is missing. " .sp It is checked by \fBgetseuserbyname\fR(3) that is called by SELinux-aware login applications such as \fBPAM\fR(8). .sp If set to \fI0\fR or the entry missing: .RS .BR getseuserbyname "(3) will return the GNU / Linux user name as the SELinux user." .RE .sp If set to \fI1\fR: .RS .BR getseuserbyname "(3) will fail." .RE .sp The \fBgetseuserbyname\fR(3) man page should be consulted for its use. The format of the \fIseusers\fR file is shown in \fBseusers\fR(5). .sp .RE .sp .B AUTORELABEL .RS This is an optional entry that allows the file system to be relabeled. .sp If set to \fI0\fR and there is a file called \fI.autorelabel\fR in the root directory, then on a reboot, the loader will drop to a shell where a root login is required. An administrator can then manually relabel the file system. .sp If set to \fI1\fR or no entry present (the default) and there is a \fI.autorelabel\fR file in the root directory, then the file system will be automatically relabeled using \fBfixfiles \-F restore\fR .sp In both cases the \fI/.autorelabel\fR file will be removed so that relabeling is not done again. .RE .sp .SH "EXAMPLE" This example \fIconfig\fR file shows the minimum contents for a system to run SELinux in enforcing mode, with a \fIpolicy_name\fR of 'targeted': .sp .RS SELINUX = enforcing .br SELINUXTYPE = targeted .RE .SH "SEE ALSO" .BR selinux "(8), " sestatus "(8), " selinux_path "(3), " selinux_policy_root_path "(3), " selinux_binary_policy_path "(3), " getseuserbyname "(3), " PAM "(8), " fixfiles "(8), " selinux_mkload_policy "(3), " selinux_getpolicytype "(3), " security_policyvers "(3), " selinux_getenforcemode "(3), " seusers "(5) " policycoreutils-3.3/man/ru/000077500000000000000000000000001413427467300160245ustar00rootroot00000000000000policycoreutils-3.3/man/ru/man5/000077500000000000000000000000001413427467300166645ustar00rootroot00000000000000policycoreutils-3.3/man/ru/man5/selinux_config.5000066400000000000000000000207111413427467300217670ustar00rootroot00000000000000.TH "selinux_config" "5" "18 ноября 2011" "Security Enhanced Linux" "Файл конфигурации SELinux" .SH "ИМЯ" config \- файл конфигурации подсистемы SELinux. .SH "ОПИСАНИЕ" Файл \fIconfig\fR SELinux управляет состоянием SELinux, определяя: .RS .IP "1." 4 Состояние применения политики \- \fIenforcing\fR (принудительный режим), \fIpermissive\fR (разрешительный режим) или \fIdisabled\fR (отключена). .IP "2." 4 Имя политики или тип, формирующий путь к политике, которую следует загрузить, и её вспомогательным файлам конфигурации. .IP "3." 4 Способ управления локальными пользователями и логическими переключателями после загрузки политики (обратите внимание, что эта возможность использовалась в предыдущих версиях SELinux, сейчас она устарела). .IP "4." 4 Поведение поддерживающих SELinux приложений при отсутствии настроенных действительных пользователей SELinux. .IP "5." 4 Следует ли повторно проставлять метки в системе. .RE Описание записей, которые управляют этими возможностями, приводится в разделе \fBФОРМАТ ФАЙЛА\fR. .sp Полный путь к файлу конфигурации SELinux: \fI/etc/selinux/config\fR. .sp Если файл \fIconfig\fR отсутствует или повреждён, политика SELinux не будет загружена (то есть SELinux будет отключён). .sp Команда \fBsestatus\fR (8) и функция libselinux \fBselinux_path\fR (3) возвращают расположение файла \fIconfig\fR. .SH "ФОРМАТ ФАЙЛА" Файл \fIconfig\fR поддерживает следующие параметры: .sp .RS \fBSELINUX = \fIenforcing\fR | \fIpermissive\fR | \fIdisabled\fR .br \fBSELINUXTYPE = \fIpolicy_name\fR .br \fBREQUIREUSERS = \fI0\fR | \fI1\fR .br \fBAUTORELABEL = \fI0\fR | \fI1\fR .RE .sp Где: .br .B SELINUX .RS Эта запись может содержать одно из трёх значений: .RS .IP \fIenforcing\fR 4 Политика безопасности SELinux применяется. .IP \fIpermissive\fR 4 Политика безопасности SELinux не применяется, но ведётся журналирование предупреждений (то есть действиям разрешено продолжать выполняться). .IP \fIdisabled\fR SELinux отключён, политика не загружена. .RE .sp Значение записи можно узнать с помощью команды \fBsestatus\fR(8) или \fBselinux_getenforcemode\fR(3). .RE .sp .B SELINUXTYPE .RS Запись \fIpolicy_name\fR используется для идентификации типа политики и становится именем каталога, в котором располагаются политика и её файлы конфигурации. .sp Значение записи можно узнать с помощью команды \fBsestatus\fR(8) или \fBselinux_getpolicytype\fR(3). .sp \fIpolicy_name\fR относится к пути, который определён внутри подсистемы SELinux и может быть получен с помощью \fBselinux_path\fR(3). Пример записи, полученной с помощью \fBselinux_path\fR(3): .br .RS .I /etc/selinux/ .RE .sp Затем к концу этой записи добавляется \fIpolicy_name\fR, и она становится корневым расположением политики, которое может быть получено с помощью \fBselinux_policy_root_path\fR(3). Пример полученной записи: .RS .I /etc/selinux/targeted .RE .sp Фактическая двоичная политика расположена относительно этого каталога и также имеет предварительно выделенное имя политики. Эту информацию можно получить с помощью \fBselinux_binary_policy_path\fR(3). Пример записи, полученной с помощью \fBselinux_binary_policy_path\fR(3): .br .RS .I /etc/selinux/targeted/policy/policy .RE .sp По соглашению к концу имени двоичной политики добавляется версия политики SELinux, которую она поддерживает. Максимальную версию политики, поддерживаемую ядром, можно определить с помощью команды \fBsestatus\fR(8) или \fBsecurity_policyvers\fR(3). Пример файла двоичной политики с версией: .br .RS .I /etc/selinux/targeted/policy/policy.24 .RE .RE .sp .B REQUIRESEUSERS .RS Эта необязательная запись позволяет сделать попытку входа неудачной, если в файле .BR seusers "(5) нет соответствующей записи или записи по умолчанию или отсутствует сам файл " seusers ". " .sp Она проверяется функцией \fBgetseuserbyname\fR(3), которая вызывается поддерживающими SELinux приложениями для входа, например, \fBPAM\fR(8). .sp Если задано значение \fI0\fR или отсутствует запись: .RS .BR getseuserbyname "(3) вернёт имя пользователя GNU / Linux в качестве пользователя SELinux." .RE .sp Если задано значение \fI1\fR: .RS .BR getseuserbyname "(3) не удастся выполнить." .RE .sp Описание работы \fBgetseuserbyname\fR(3) содержится на соответствующей man-странице. Формат файла \fIseusers\fR показан в \fBseusers\fR(5). .sp .RE .sp .B AUTORELABEL .RS Эта необязательная запись позволяет повторно проставлять метки в файловой системе. .sp Если задано значение \fI0\fR и в корневом каталоге имеется файл с именем \fI.autorelabel\fR, при перезагрузке загрузчик перейдёт в оболочку, запрашивающую вход в качестве пользователя root. Затем администратор сможет вручную проставить метки в файловой системе. .sp Если задано значение \fI1\fR или запись отсутствует (состояние по умолчанию) и в корневом каталоге имеется файл \fI.autorelabel\fR, в файловой системе с помощью \fBfixfiles \-F restore\fR будут автоматически повторно проставлены метки. .sp В обоих случаях файл \fI/.autorelabel\fR будет удалён, чтобы предотвратить последующее повторное проставление меток. .RE .sp .SH "ПРИМЕР" В этом примере показано минимальное содержимое файла \fIconfig\fR, которое обеспечит запуск SELinux в системе в принудительном режиме, со значением \fIpolicy_name\fR 'targeted': .sp .RS SELINUX = enforcing .br SELINUXTYPE = targeted .RE .SH "СМОТРИТЕ ТАКЖЕ" .BR selinux "(8), " sestatus "(8), " selinux_path "(3), " selinux_policy_root_path "(3), " selinux_binary_policy_path "(3), " getseuserbyname "(3), " PAM "(8), " fixfiles "(8), " selinux_mkload_policy "(3), " selinux_getpolicytype "(3), " security_policyvers "(3), " selinux_getenforcemode "(3), " seusers "(5) " .SH АВТОРЫ Перевод на русский язык выполнила Герасименко Олеся . policycoreutils-3.3/newrole/000077500000000000000000000000001413427467300162765ustar00rootroot00000000000000policycoreutils-3.3/newrole/Makefile000066400000000000000000000054331413427467300177430ustar00rootroot00000000000000# Installation directories. LINGUAS ?= ru PREFIX ?= /usr BINDIR ?= $(PREFIX)/bin MANDIR ?= $(PREFIX)/share/man ETCDIR ?= /etc LOCALEDIR = $(DESTDIR)$(PREFIX)/share/locale INCLUDEDIR ?= $(PREFIX)/include PAMH ?= $(shell test -f $(INCLUDEDIR)/security/pam_appl.h && echo y) AUDITH ?= $(shell test -f $(INCLUDEDIR)/libaudit.h && echo y) # Enable capabilities to permit newrole to generate audit records. # This will make newrole a setuid root program. # The capabilities used are: CAP_AUDIT_WRITE. AUDIT_LOG_PRIV ?= n # Enable capabilities to permit newrole to utilize the pam_namespace module. # This will make newrole a setuid root program. # The capabilities used are: CAP_SYS_ADMIN, CAP_CHOWN, CAP_FOWNER and # CAP_DAC_OVERRIDE. NAMESPACE_PRIV ?= n # If LSPP_PRIV is y, then newrole will be made into setuid root program. # Enabling this option will force AUDIT_LOG_PRIV and NAMESPACE_PRIV to be y. LSPP_PRIV ?= n VERSION = $(shell cat ../VERSION) CFLAGS ?= -Werror -Wall -W EXTRA_OBJS = override CFLAGS += -DVERSION=\"$(VERSION)\" -DUSE_NLS -DLOCALEDIR="\"$(LOCALEDIR)\"" -DPACKAGE="\"policycoreutils\"" override LDLIBS += -lselinux ifeq ($(PAMH), y) override CFLAGS += -DUSE_PAM EXTRA_OBJS += hashtab.o override LDLIBS += -lpam -lpam_misc else override CFLAGS += -D_XOPEN_SOURCE=500 override LDLIBS += -lcrypt endif ifeq ($(AUDITH), y) override CFLAGS += -DUSE_AUDIT override LDLIBS += -laudit endif ifeq ($(LSPP_PRIV),y) override AUDIT_LOG_PRIV=y override NAMESPACE_PRIV=y endif ifeq ($(AUDIT_LOG_PRIV),y) override CFLAGS += -DAUDIT_LOG_PRIV IS_SUID=y endif ifeq ($(NAMESPACE_PRIV),y) override CFLAGS += -DNAMESPACE_PRIV IS_SUID=y endif ifeq ($(IS_SUID),y) MODE := 4555 override LDLIBS += -lcap-ng else MODE := 0555 endif all: newrole newrole: newrole.o $(EXTRA_OBJS) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) install: all test -d $(DESTDIR)$(BINDIR) || install -m 755 -d $(DESTDIR)$(BINDIR) test -d $(DESTDIR)$(ETCDIR)/pam.d || install -m 755 -d $(DESTDIR)$(ETCDIR)/pam.d test -d $(DESTDIR)$(MANDIR)/man1 || install -m 755 -d $(DESTDIR)$(MANDIR)/man1 install -m $(MODE) newrole $(DESTDIR)$(BINDIR) install -m 644 newrole.1 $(DESTDIR)$(MANDIR)/man1/ for lang in $(LINGUAS) ; do \ if [ -e $${lang} ] ; then \ test -d $(DESTDIR)$(MANDIR)/$${lang}/man1 || install -m 755 -d $(DESTDIR)$(MANDIR)/$${lang}/man1 ; \ install -m 644 $${lang}/*.1 $(DESTDIR)$(MANDIR)/$${lang}/man1/ ; \ fi ; \ done ifeq ($(PAMH), y) test -d $(DESTDIR)$(ETCDIR)/pam.d || install -m 755 -d $(DESTDIR)$(ETCDIR)/pam.d ifeq ($(LSPP_PRIV),y) install -m 644 newrole-lspp.pamd $(DESTDIR)$(ETCDIR)/pam.d/newrole else install -m 644 newrole.pamd $(DESTDIR)$(ETCDIR)/pam.d/newrole endif endif clean: rm -f newrole *.o indent: ../../scripts/Lindent $(wildcard *.[ch]) relabel: install /sbin/restorecon $(DESTDIR)$(BINDIR)/newrole policycoreutils-3.3/newrole/hashtab.c000066400000000000000000000075001413427467300200560ustar00rootroot00000000000000 /* Author : Stephen Smalley, */ /* FLASK */ /* * Implementation of the hash table type. */ #include #include #include "hashtab.h" hashtab_t hashtab_create(unsigned int (*hash_value) (hashtab_t h, const_hashtab_key_t key), int (*keycmp) (hashtab_t h, const_hashtab_key_t key1, const_hashtab_key_t key2), unsigned int size) { hashtab_t p; unsigned int i; p = (hashtab_t) malloc(sizeof(hashtab_val_t)); if (p == NULL) return p; memset(p, 0, sizeof(hashtab_val_t)); p->size = size; p->nel = 0; p->hash_value = hash_value; p->keycmp = keycmp; p->htable = (hashtab_ptr_t *) malloc(sizeof(hashtab_ptr_t) * size); if (p->htable == NULL) { free(p); return NULL; } for (i = 0; i < size; i++) p->htable[i] = (hashtab_ptr_t) NULL; return p; } int hashtab_insert(hashtab_t h, hashtab_key_t key, hashtab_datum_t datum) { int hvalue; hashtab_ptr_t prev, cur, newnode; if (!h) return HASHTAB_OVERFLOW; hvalue = h->hash_value(h, key); prev = NULL; cur = h->htable[hvalue]; while (cur && h->keycmp(h, key, cur->key) > 0) { prev = cur; cur = cur->next; } if (cur && (h->keycmp(h, key, cur->key) == 0)) return HASHTAB_PRESENT; newnode = (hashtab_ptr_t) malloc(sizeof(hashtab_node_t)); if (newnode == NULL) return HASHTAB_OVERFLOW; memset(newnode, 0, sizeof(struct hashtab_node)); newnode->key = key; newnode->datum = datum; if (prev) { newnode->next = prev->next; prev->next = newnode; } else { newnode->next = h->htable[hvalue]; h->htable[hvalue] = newnode; } h->nel++; return HASHTAB_SUCCESS; } int hashtab_remove(hashtab_t h, hashtab_key_t key, void (*destroy) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args) { int hvalue; hashtab_ptr_t cur, last; if (!h) return HASHTAB_MISSING; hvalue = h->hash_value(h, key); last = NULL; cur = h->htable[hvalue]; while (cur != NULL && h->keycmp(h, key, cur->key) > 0) { last = cur; cur = cur->next; } if (cur == NULL || (h->keycmp(h, key, cur->key) != 0)) return HASHTAB_MISSING; if (last == NULL) h->htable[hvalue] = cur->next; else last->next = cur->next; if (destroy) destroy(cur->key, cur->datum, args); free(cur); h->nel--; return HASHTAB_SUCCESS; } hashtab_datum_t hashtab_search(hashtab_t h, const_hashtab_key_t key) { int hvalue; hashtab_ptr_t cur; if (!h) return NULL; hvalue = h->hash_value(h, key); cur = h->htable[hvalue]; while (cur != NULL && h->keycmp(h, key, cur->key) > 0) cur = cur->next; if (cur == NULL || (h->keycmp(h, key, cur->key) != 0)) return NULL; return cur->datum; } void hashtab_destroy(hashtab_t h) { unsigned int i; hashtab_ptr_t cur, temp; if (!h) return; for (i = 0; i < h->size; i++) { cur = h->htable[i]; while (cur != NULL) { temp = cur; cur = cur->next; free(temp); } h->htable[i] = NULL; } free(h->htable); h->htable = NULL; free(h); } int hashtab_map(hashtab_t h, int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args) { unsigned int i, ret; hashtab_ptr_t cur; if (!h) return HASHTAB_SUCCESS; for (i = 0; i < h->size; i++) { cur = h->htable[i]; while (cur != NULL) { ret = apply(cur->key, cur->datum, args); if (ret) return ret; cur = cur->next; } } return HASHTAB_SUCCESS; } void hashtab_hash_eval(hashtab_t h, char *tag) { unsigned int i; int chain_len, slots_used, max_chain_len; hashtab_ptr_t cur; slots_used = 0; max_chain_len = 0; for (i = 0; i < h->size; i++) { cur = h->htable[i]; if (cur) { slots_used++; chain_len = 0; while (cur) { chain_len++; cur = cur->next; } if (chain_len > max_chain_len) max_chain_len = chain_len; } } printf ("%s: %d entries and %d/%d buckets used, longest chain length %d\n", tag, h->nel, slots_used, h->size, max_chain_len); } policycoreutils-3.3/newrole/hashtab.h000066400000000000000000000067011413427467300200650ustar00rootroot00000000000000 /* Author : Stephen Smalley, */ /* FLASK */ /* * A hash table (hashtab) maintains associations between * key values and datum values. The type of the key values * and the type of the datum values is arbitrary. The * functions for hash computation and key comparison are * provided by the creator of the table. */ #ifndef _NEWROLE_HASHTAB_H_ #define _NEWROLE_HASHTAB_H_ #include #include #include typedef char *hashtab_key_t; /* generic key type */ typedef const char *const_hashtab_key_t; /* constant generic key type */ typedef void *hashtab_datum_t; /* generic datum type */ typedef struct hashtab_node *hashtab_ptr_t; typedef struct hashtab_node { hashtab_key_t key; hashtab_datum_t datum; hashtab_ptr_t next; } hashtab_node_t; typedef struct hashtab_val { hashtab_ptr_t *htable; /* hash table */ unsigned int size; /* number of slots in hash table */ uint32_t nel; /* number of elements in hash table */ unsigned int (*hash_value) (struct hashtab_val * h, const_hashtab_key_t key); /* hash function */ int (*keycmp) (struct hashtab_val * h, const_hashtab_key_t key1, const_hashtab_key_t key2); /* key comparison function */ } hashtab_val_t; typedef hashtab_val_t *hashtab_t; /* Define status codes for hash table functions */ #define HASHTAB_SUCCESS 0 #define HASHTAB_OVERFLOW -ENOMEM #define HASHTAB_PRESENT -EEXIST #define HASHTAB_MISSING -ENOENT /* Creates a new hash table with the specified characteristics. Returns NULL if insufficient space is available or the new hash table otherwise. */ extern hashtab_t hashtab_create(unsigned int (*hash_value) (hashtab_t h, const_hashtab_key_t key), int (*keycmp) (hashtab_t h, const_hashtab_key_t key1, const_hashtab_key_t key2), unsigned int size); /* Inserts the specified (key, datum) pair into the specified hash table. Returns HASHTAB_OVERFLOW if insufficient space is available or HASHTAB_PRESENT if there is already an entry with the same key or HASHTAB_SUCCESS otherwise. */ extern int hashtab_insert(hashtab_t h, hashtab_key_t k, hashtab_datum_t d); /* Removes the entry with the specified key from the hash table. Applies the specified destroy function to (key,datum,args) for the entry. Returns HASHTAB_MISSING if no entry has the specified key or HASHTAB_SUCCESS otherwise. */ extern int hashtab_remove(hashtab_t h, hashtab_key_t k, void (*destroy) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args); /* Searches for the entry with the specified key in the hash table. Returns NULL if no entry has the specified key or the datum of the entry otherwise. */ extern hashtab_datum_t hashtab_search(hashtab_t h, const_hashtab_key_t k); /* Destroys the specified hash table. */ extern void hashtab_destroy(hashtab_t h); /* Applies the specified apply function to (key,datum,args) for each entry in the specified hash table. The order in which the function is applied to the entries is dependent upon the internal structure of the hash table. If apply returns a non-zero status, then hashtab_map will cease iterating through the hash table and will propagate the error return to its caller. */ extern int hashtab_map(hashtab_t h, int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args); extern void hashtab_hash_eval(hashtab_t h, char *tag); #endif policycoreutils-3.3/newrole/newrole-lspp.pamd000066400000000000000000000002541413427467300215710ustar00rootroot00000000000000#%PAM-1.0 auth include system-auth account include system-auth password include system-auth session required pam_namespace.so unmnt_remnt no_unmount_on_close policycoreutils-3.3/newrole/newrole.1000066400000000000000000000063411413427467300200370ustar00rootroot00000000000000.TH NEWROLE "1" "October 2000" "Security Enhanced Linux" NSA .SH NAME newrole \- run a shell with a new SELinux role .SH SYNOPSIS .B newrole [\fB-r\fR|\fB--role\fR] \fIROLE\fR [\fB-t\fR|\fB--type\fR] \fITYPE\fR [\fB-l\fR|\fB--level\fR] [\fB-p\fR|\fB--preserve-environment\fR] \fILEVEL\fR [-- [\fIARGS\fR]...] .SH DESCRIPTION .PP Run a new shell in a new context. The new context is derived from the old context in which .B newrole is originally executed. If the .B -r or .B --role option is specified, then the new context will have the role specified by \fIROLE\fR. If the .B -t or .B --type option is specified, then the new context will have the type (domain) specified by \fITYPE\fR. If a role is specified, but no type is specified, the default type is derived from the specified role. If the .B -l or .B --level option is specified, then the new context will have the sensitivity level specified by \fILEVEL\fR. If \fILEVEL\fR is a range, the new context will have the sensitivity level and clearance specified by that range. If the .B -p or .B --preserve-environment option is specified, the shell with the new SELinux context will preserve environment variables, otherwise a new minimal environment is created. .PP Additional arguments .I ARGS may be provided after a -- option, in which case they are supplied to the new shell. In particular, an argument of \-\- \-c will cause the next argument to be treated as a command by most command interpreters. .PP If a command argument is specified to newrole and the command name is found in /etc/selinux/newrole_pam.conf, then the pam service name listed in that file for the command will be used rather than the normal newrole pam configuration. This allows for per-command pam configuration when invoked via newrole, e.g. to skip the interactive re-authentication phase. .PP The new shell will be the shell specified in the user's entry in the .I /etc/passwd file. .PP The .B -V or .B --version shows the current version of newrole .PP .SH EXAMPLE .br Changing role: # id \-Z staff_u:staff_r:staff_t:SystemLow-SystemHigh # newrole \-r sysadm_r # id \-Z staff_u:sysadm_r:sysadm_t:SystemLow-SystemHigh Changing sensitivity only: # id \-Z staff_u:sysadm_r:sysadm_t:Unclassified-SystemHigh # newrole \-l Secret # id \-Z staff_u:sysadm_r:sysadm_t:Secret-SystemHigh .PP Changing sensitivity and clearance: # id \-Z staff_u:sysadm_r:sysadm_t:Unclassified-SystemHigh # newrole \-l Secret-Secret # id \-Z staff_u:sysadm_r:sysadm_t:Secret .PP Running a program in a given role or level: # newrole \-r sysadm_r \-\- \-c "/path/to/app arg1 arg2..." # newrole \-l Secret \-\- \-c "/path/to/app arg1 arg2..." .SH FILES /etc/passwd - user account information .br /etc/shadow - encrypted passwords and age information .br /etc/selinux//contexts/default_type - default types for roles .br /etc/selinux//contexts/securetty_types - securetty types for level changes .br /etc/selinux/newrole_pam.conf - optional mapping of commands to separate pam service names .br .SH SEE ALSO .BR runcon (1) .SH AUTHORS .nf Anthony Colatrella Tim Fraser Steve Grubb Darrel Goeddel Michael Thompson Dan Walsh policycoreutils-3.3/newrole/newrole.c000066400000000000000000001055471413427467300201310ustar00rootroot00000000000000/************************************************************************ * * newrole * * SYNOPSIS: * * This program allows a user to change their SELinux RBAC role and/or * SELinux TE type (domain) in a manner similar to the way the traditional * UNIX su program allows a user to change their identity. * * USAGE: * * newrole [ -r role ] [ -t type ] [ -l level ] [ -V ] [ -- args ] * * BUILD OPTIONS: * * option USE_PAM: * * Set the USE_PAM constant if you want to authenticate users via PAM. * If USE_PAM is not set, users will be authenticated via direct * access to the shadow password file. * * If you decide to use PAM must be told how to handle newrole. A * good rule-of-thumb might be to tell PAM to handle newrole in the * same way it handles su, except that you should remove the pam_rootok.so * entry so that even root must re-authenticate to change roles. * * If you choose not to use PAM, make sure you have a shadow passwd file * in /etc/shadow. You can use a symlink if your shadow passwd file * lives in another directory. Example: * su * cd /etc * ln -s /etc/auth/shadow shadow * * If you decide not to use PAM, you will also have to make newrole * setuid root, so that it can read the shadow passwd file. * * * Authors: * Anthony Colatrella * Tim Fraser * Steve Grubb * Darrel Goeddel * Michael Thompson * Dan Walsh * *************************************************************************/ #define _GNU_SOURCE #if defined(AUDIT_LOG_PRIV) && !defined(USE_AUDIT) #error AUDIT_LOG_PRIV needs the USE_AUDIT option #endif #if defined(NAMESPACE_PRIV) && !defined(USE_PAM) #error NAMESPACE_PRIV needs the USE_PAM option #endif #include #include /* for malloc(), realloc(), free() */ #include /* for getpwuid() */ #include #include /* to make getuid() and getpwuid() happy */ #include /* for wait() */ #include /* for getopt_long() form of getopt() */ #include #include #include #include /* for is_selinux_enabled() */ #include /* for context-mangling functions */ #include #include /* for SELINUX_DEFAULTUSER */ #include #include /* for getuid(), exit(), getopt() */ #ifdef USE_AUDIT #include #endif #if defined(AUDIT_LOG_PRIV) || defined(NAMESPACE_PRIV) #include #include #endif #ifdef USE_NLS #include /* for setlocale() */ #include /* for gettext() */ #define _(msgid) gettext (msgid) #else #define _(msgid) (msgid) #endif #ifndef PACKAGE #define PACKAGE "policycoreutils" /* the name of this package lang translation */ #endif #define TRUE 1 #define FALSE 0 /* USAGE_STRING describes the command-line args of this program. */ #define USAGE_STRING "USAGE: newrole [ -r role ] [ -t type ] [ -l level ] [ -p ] [ -V ] [ -- args ]" #ifdef USE_PAM #define PAM_SERVICE_CONFIG "/etc/selinux/newrole_pam.conf" #endif #define DEFAULT_PATH "/usr/bin:/bin" #define DEFAULT_CONTEXT_SIZE 255 /* first guess at context size */ extern char **environ; /** * Construct from the current range and specified desired level a resulting * range. If the specified level is a range, return that. If it is not, then * construct a range with level as the sensitivity and clearance of the current * context. * * newlevel - the level specified on the command line * range - the range in the current context * * Returns malloc'd memory */ static char *build_new_range(char *newlevel, const char *range) { char *newrangep = NULL; const char *tmpptr; size_t len; /* a missing or empty string */ if (!range || !strlen(range) || !newlevel || !strlen(newlevel)) return NULL; /* if the newlevel is actually a range - just use that */ if (strchr(newlevel, '-')) { newrangep = strdup(newlevel); return newrangep; } /* look for MLS range in current context */ tmpptr = strchr(range, '-'); if (tmpptr) { /* we are inserting into a ranged MLS context */ len = strlen(newlevel) + 1 + strlen(tmpptr + 1) + 1; newrangep = (char *)malloc(len); if (!newrangep) return NULL; snprintf(newrangep, len, "%s-%s", newlevel, tmpptr + 1); } else { /* we are inserting into a currently non-ranged MLS context */ if (!strcmp(newlevel, range)) { newrangep = strdup(range); } else { len = strlen(newlevel) + 1 + strlen(range) + 1; newrangep = (char *)malloc(len); if (!newrangep) return NULL; snprintf(newrangep, len, "%s-%s", newlevel, range); } } return newrangep; } #ifdef USE_PAM /************************************************************************ * * All PAM code goes in this section. * ************************************************************************/ #include /* for PAM functions */ #include /* for misc_conv PAM utility function */ const char *service_name = "newrole"; /* authenticate_via_pam() * * in: pw - struct containing data from our user's line in * the passwd file. * out: nothing * return: value condition * ----- --------- * 1 PAM thinks that the user authenticated themselves properly * 0 otherwise * * This function uses PAM to authenticate the user running this * program. This is the only function in this program that makes PAM * calls. */ int authenticate_via_pam(const char *ttyn, pam_handle_t * pam_handle) { int result = 0; /* set to 0 (not authenticated) by default */ int pam_rc; /* pam return code */ const char *tty_name; if (ttyn) { if (strncmp(ttyn, "/dev/", 5) == 0) tty_name = ttyn + 5; else tty_name = ttyn; pam_rc = pam_set_item(pam_handle, PAM_TTY, tty_name); if (pam_rc != PAM_SUCCESS) { fprintf(stderr, _("failed to set PAM_TTY\n")); goto out; } } /* Ask PAM to authenticate the user running this program */ pam_rc = pam_authenticate(pam_handle, 0); if (pam_rc != PAM_SUCCESS) { goto out; } /* Ask PAM to verify acct_mgmt */ pam_rc = pam_acct_mgmt(pam_handle, 0); if (pam_rc == PAM_SUCCESS) { result = 1; /* user authenticated OK! */ } out: return result; } /* authenticate_via_pam() */ #include "hashtab.h" static int free_hashtab_entry(hashtab_key_t key, hashtab_datum_t d, void *args __attribute__ ((unused))) { free(key); free(d); return 0; } static unsigned int reqsymhash(hashtab_t h, const_hashtab_key_t key) { char *p, *keyp; size_t size; unsigned int val; val = 0; keyp = (char *)key; size = strlen(keyp); for (p = keyp; ((size_t) (p - keyp)) < size; p++) val = (val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p); return val & (h->size - 1); } static int reqsymcmp(hashtab_t h __attribute__ ((unused)), const_hashtab_key_t key1, const_hashtab_key_t key2) { return strcmp(key1, key2); } static hashtab_t app_service_names = NULL; #define PAM_SERVICE_SLOTS 64 static int process_pam_config(FILE * cfg) { const char *config_file_path = PAM_SERVICE_CONFIG; char *line_buf = NULL; unsigned long lineno = 0; size_t len = 0; char *app = NULL; char *service = NULL; int ret; while (getline(&line_buf, &len, cfg) > 0) { char *buffer = line_buf; lineno++; while (isspace(*buffer)) buffer++; if (buffer[0] == '#') continue; if (buffer[0] == '\n' || buffer[0] == '\0') continue; app = service = NULL; ret = sscanf(buffer, "%ms %ms\n", &app, &service); if (ret < 2 || !app || !service) goto err; ret = hashtab_insert(app_service_names, app, service); if (ret == HASHTAB_OVERFLOW) { fprintf(stderr, _ ("newrole: service name configuration hashtable overflow\n")); goto err; } } free(line_buf); return 0; err: free(app); free(service); fprintf(stderr, _("newrole: %s: error on line %lu.\n"), config_file_path, lineno); free(line_buf); return -1; } /* * Read config file ignoring comment lines. * Files specified one per line executable with a corresponding * pam service name. */ static int read_pam_config(void) { const char *config_file_path = PAM_SERVICE_CONFIG; FILE *cfg = NULL; cfg = fopen(config_file_path, "r"); if (!cfg) return 0; /* This configuration is optional. */ app_service_names = hashtab_create(reqsymhash, reqsymcmp, PAM_SERVICE_SLOTS); if (!app_service_names) goto err; if (process_pam_config(cfg)) goto err; fclose(cfg); return 0; err: fclose(cfg); return -1; } #else /* else !USE_PAM */ /************************************************************************ * * All shadow passwd code goes in this section. * ************************************************************************/ #include /* for shadow passwd functions */ #include /* for strlen(), memset() */ #define PASSWORD_PROMPT _("Password:") /* prompt for getpass() */ /* authenticate_via_shadow_passwd() * * in: uname - the calling user's user name * out: nothing * return: value condition * ----- --------- * 1 user authenticated themselves properly according to the * shadow passwd file. * 0 otherwise * * This function uses the shadow passwd file to thenticate the user running * this program. */ int authenticate_via_shadow_passwd(const char *uname) { struct spwd *p_shadow_line; char *unencrypted_password_s; char *encrypted_password_s; setspent(); p_shadow_line = getspnam(uname); endspent(); if (!(p_shadow_line)) { fprintf(stderr, _("Cannot find your entry in the shadow " "passwd file.\n")); return 0; } /* Ask user to input unencrypted password */ if (!(unencrypted_password_s = getpass(PASSWORD_PROMPT))) { fprintf(stderr, _("getpass cannot open /dev/tty\n")); return 0; } /* Use crypt() to encrypt user's input password. */ encrypted_password_s = crypt(unencrypted_password_s, p_shadow_line->sp_pwdp); memset(unencrypted_password_s, 0, strlen(unencrypted_password_s)); return (!strcmp(encrypted_password_s, p_shadow_line->sp_pwdp)); } #endif /* if/else USE_PAM */ /** * This function checks to see if the shell is known in /etc/shells. * If so, it returns 1. On error or illegal shell, it returns 0. */ static int verify_shell(const char *shell_name) { int found = 0; const char *buf; if (!(shell_name && shell_name[0])) return found; while ((buf = getusershell()) != NULL) { /* ignore comments */ if (*buf == '#') continue; /* check the shell skipping newline char */ if (!strcmp(shell_name, buf)) { found = 1; break; } } endusershell(); return found; } /** * Determine the Linux user identity to re-authenticate. * If supported and set, use the login uid, as this should be more stable. * Otherwise, use the real uid. * * This function assigns malloc'd memory into the pw_copy struct. * Returns zero on success, non-zero otherwise */ static int extract_pw_data(struct passwd *pw_copy) { uid_t uid; struct passwd *pw; #ifdef USE_AUDIT uid = audit_getloginuid(); if (uid == (uid_t) - 1) uid = getuid(); #else uid = getuid(); #endif setpwent(); pw = getpwuid(uid); endpwent(); if (!(pw && pw->pw_name && pw->pw_name[0] && pw->pw_shell && pw->pw_shell[0] && pw->pw_dir && pw->pw_dir[0])) { fprintf(stderr, _("cannot find valid entry in the passwd file.\n")); return -1; } *pw_copy = *pw; pw = pw_copy; pw->pw_name = strdup(pw->pw_name); pw->pw_dir = strdup(pw->pw_dir); pw->pw_shell = strdup(pw->pw_shell); if (!(pw->pw_name && pw->pw_dir && pw->pw_shell)) { fprintf(stderr, _("Out of memory!\n")); goto out_free; } if (verify_shell(pw->pw_shell) == 0) { fprintf(stderr, _("Error! Shell is not valid.\n")); goto out_free; } return 0; out_free: free(pw->pw_name); free(pw->pw_dir); free(pw->pw_shell); pw->pw_name = NULL; pw->pw_dir = NULL; pw->pw_shell = NULL; return -1; } /** * Either restore the original environment, or set up a minimal one. * * The minimal environment contains: * TERM, DISPLAY and XAUTHORITY - if they are set, preserve values * HOME, SHELL, USER and LOGNAME - set to contents of /etc/passwd * PATH - set to default value DEFAULT_PATH * * Returns zero on success, non-zero otherwise */ static int restore_environment(int preserve_environment, char **old_environ, const struct passwd *pw) { char const *term_env; char const *display_env; char const *xauthority_env; char *term = NULL; /* temporary container */ char *display = NULL; /* temporary container */ char *xauthority = NULL; /* temporary container */ int rc; environ = old_environ; if (preserve_environment) return 0; term_env = getenv("TERM"); display_env = getenv("DISPLAY"); xauthority_env = getenv("XAUTHORITY"); /* Save the variable values we want */ if (term_env) term = strdup(term_env); if (display_env) display = strdup(display_env); if (xauthority_env) xauthority = strdup(xauthority_env); if ((term_env && !term) || (display_env && !display) || (xauthority_env && !xauthority)) { rc = -1; goto out; } /* Construct a new environment */ if ((rc = clearenv())) { fprintf(stderr, _("Unable to clear environment\n")); goto out; } /* Restore that which we saved */ if (term) rc |= setenv("TERM", term, 1); if (display) rc |= setenv("DISPLAY", display, 1); if (xauthority) rc |= setenv("XAUTHORITY", xauthority, 1); rc |= setenv("HOME", pw->pw_dir, 1); rc |= setenv("SHELL", pw->pw_shell, 1); rc |= setenv("USER", pw->pw_name, 1); rc |= setenv("LOGNAME", pw->pw_name, 1); rc |= setenv("PATH", DEFAULT_PATH, 1); out: free(term); free(display); free(xauthority); return rc; } /** * This function will drop the capabilities so that we are left * only with access to the audit system. If the user is root, we leave * the capabilities alone since they already should have access to the * audit netlink socket. * * Returns zero on success, non-zero otherwise */ #if defined(AUDIT_LOG_PRIV) && !defined(NAMESPACE_PRIV) static int drop_capabilities(int full) { uid_t uid = getuid(); if (!uid) return 0; capng_setpid(getpid()); capng_clear(CAPNG_SELECT_CAPS); if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n")); return -1; } /* Change uid */ if (setresuid(uid, uid, uid)) { fprintf(stderr, _("Error changing uid, aborting.\n")); return -1; } if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0) { fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n")); return -1; } if (! full) capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_AUDIT_WRITE); return capng_apply(CAPNG_SELECT_CAPS); } #elif defined(NAMESPACE_PRIV) /** * This function will drop the capabilities so that we are left * only with access to the audit system and the ability to raise * CAP_SYS_ADMIN, CAP_DAC_OVERRIDE, CAP_FOWNER and CAP_CHOWN, * before invoking pam_namespace. These capabilities are needed * for performing bind mounts/unmounts and to create potential new * instance directories with appropriate DAC attributes. If the * user is root, we leave the capabilities alone since they already * should have access to the audit netlink socket and should have * the ability to create/mount/unmount instance directories. * * Returns zero on success, non-zero otherwise */ static int drop_capabilities(int full) { uid_t uid = getuid(); if (!uid) return 0; capng_setpid(getpid()); capng_clear(CAPNG_SELECT_CAPS); if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n")); return -1; } /* Change uid */ if (setresuid(uid, uid, uid)) { fprintf(stderr, _("Error changing uid, aborting.\n")); return -1; } if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0) { fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n")); return -1; } if (! full) capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SYS_ADMIN , CAP_FOWNER , CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_AUDIT_WRITE, -1); return capng_apply(CAPNG_SELECT_CAPS); } #else static inline int drop_capabilities(__attribute__ ((__unused__)) int full) { return 0; } #endif #ifdef NAMESPACE_PRIV /** * This function will set the uid values to be that of caller's uid, and * will drop any privilege which may have been raised. */ static int transition_to_caller_uid() { uid_t uid = getuid(); if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0) { fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n")); return -1; } if (setresuid(uid, uid, uid)) { fprintf(stderr, _("Error changing uid, aborting.\n")); return -1; } return 0; } #endif #ifdef AUDIT_LOG_PRIV /* Send audit message */ static int send_audit_message(int success, const char *old_context, const char *new_context, const char *ttyn) { char *msg = NULL; int rc; int audit_fd = audit_open(); if (audit_fd < 0) { fprintf(stderr, _("Error connecting to audit system.\n")); return -1; } if (asprintf(&msg, "newrole: old-context=%s new-context=%s", old_context ? old_context : "?", new_context ? new_context : "?") < 0) { fprintf(stderr, _("Error allocating memory.\n")); rc = -1; goto out; } rc = audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, msg, NULL, NULL, ttyn, success); if (rc <= 0) { fprintf(stderr, _("Error sending audit message.\n")); rc = -1; goto out; } rc = 0; out: free(msg); close(audit_fd); return rc; } #else static inline int send_audit_message(int success __attribute__ ((unused)), const char *old_context __attribute__ ((unused)), const char *new_context __attribute__ ((unused)), const char *ttyn __attribute__ ((unused))) { return 0; } #endif /** * This function attempts to relabel the tty. If this function fails, then * the fd is closed, the contexts are free'd and -1 is returned. On success, * a valid fd is returned and tty_context and new_tty_context are set. * * This function will not fail if it can not relabel the tty when selinux is * in permissive mode. */ static int relabel_tty(const char *ttyn, const char *new_context, char **tty_context, char **new_tty_context) { int fd, rc; int enforcing = security_getenforce(); char *tty_con = NULL; char *new_tty_con = NULL; if (!ttyn) return 0; if (enforcing < 0) { fprintf(stderr, _("Could not determine enforcing mode.\n")); return -1; } /* Re-open TTY descriptor */ fd = open(ttyn, O_RDWR | O_NONBLOCK); if (fd < 0) { fprintf(stderr, _("Error! Could not open %s.\n"), ttyn); return fd; } /* this craziness is to make sure we can't block on open and deadlock */ rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); if (rc) { fprintf(stderr, _("Error! Could not clear O_NONBLOCK on %s\n"), ttyn); close(fd); return rc; } if (fgetfilecon(fd, &tty_con) < 0) { fprintf(stderr, _("%s! Could not get current context " "for %s, not relabeling tty.\n"), enforcing ? "Error" : "Warning", ttyn); if (enforcing) goto close_fd; } if (tty_con && (security_compute_relabel(new_context, tty_con, string_to_security_class("chr_file"), &new_tty_con) < 0)) { fprintf(stderr, _("%s! Could not get new context for %s, " "not relabeling tty.\n"), enforcing ? "Error" : "Warning", ttyn); if (enforcing) goto close_fd; } if (new_tty_con) if (fsetfilecon(fd, new_tty_con) < 0) { fprintf(stderr, _("%s! Could not set new context for %s\n"), enforcing ? "Error" : "Warning", ttyn); freecon(new_tty_con); new_tty_con = NULL; if (enforcing) goto close_fd; } *tty_context = tty_con; *new_tty_context = new_tty_con; return fd; close_fd: freecon(tty_con); close(fd); return -1; } /** * This function attempts to revert the relabeling done to the tty. * fd - referencing the opened ttyn * ttyn - name of tty to restore * tty_context - original context of the tty * new_tty_context - context tty was relabeled to * * Returns zero on success, non-zero otherwise */ static int restore_tty_label(int fd, const char *ttyn, const char *tty_context, const char *new_tty_context) { int rc = 0; char *chk_tty_context = NULL; if (!ttyn) goto skip_relabel; if (!new_tty_context) goto skip_relabel; /* Verify that the tty still has the context set by newrole. */ if ((rc = fgetfilecon(fd, &chk_tty_context)) < 0) { fprintf(stderr, "Could not fgetfilecon %s.\n", ttyn); goto skip_relabel; } if ((rc = strcmp(chk_tty_context, new_tty_context))) { fprintf(stderr, _("%s changed labels.\n"), ttyn); goto skip_relabel; } if ((rc = fsetfilecon(fd, tty_context)) < 0) fprintf(stderr, _("Warning! Could not restore context for %s\n"), ttyn); skip_relabel: freecon(chk_tty_context); return rc; } /** * Parses and validates the provided command line options and * constructs a new context based on our old context and the * arguments specified on the command line. On success * new_context will be set to valid values, otherwise its value * is left unchanged. * * Returns zero on success, non-zero otherwise. */ static int parse_command_line_arguments(int argc, char **argv, char *ttyn, const char *old_context, char **new_context, int *preserve_environment) { int flag_index; /* flag index in argv[] */ int clflag; /* holds codes for command line flags */ char *role_s = NULL; /* role spec'd by user in argv[] */ char *type_s = NULL; /* type spec'd by user in argv[] */ char *type_ptr = NULL; /* stores malloc'd data from get_default_type */ char *level_s = NULL; /* level spec'd by user in argv[] */ char *range_ptr = NULL; char *new_con = NULL; char *tty_con = NULL; context_t context = NULL; /* manipulatable form of new_context */ const struct option long_options[] = { {"role", 1, 0, 'r'}, {"type", 1, 0, 't'}, {"level", 1, 0, 'l'}, {"preserve-environment", 0, 0, 'p'}, {"version", 0, 0, 'V'}, {NULL, 0, 0, 0} }; *preserve_environment = 0; while (1) { clflag = getopt_long(argc, argv, "r:t:l:pV", long_options, &flag_index); if (clflag == -1) break; switch (clflag) { case 'V': printf("newrole: %s version %s\n", PACKAGE, VERSION); exit(0); break; case 'p': *preserve_environment = 1; break; case 'r': if (role_s) { fprintf(stderr, _("Error: multiple roles specified\n")); return -1; } role_s = optarg; break; case 't': if (type_s) { fprintf(stderr, _("Error: multiple types specified\n")); return -1; } type_s = optarg; break; case 'l': if (!is_selinux_mls_enabled()) { fprintf(stderr, _("Sorry, -l may be used with " "SELinux MLS support.\n")); return -1; } if (level_s) { fprintf(stderr, _("Error: multiple levels " "specified\n")); return -1; } if (ttyn) { if (fgetfilecon(STDIN_FILENO, &tty_con) >= 0) { if (selinux_check_securetty_context (tty_con) < 0) { fprintf(stderr, _ ("Error: you are not allowed to change levels on a non secure terminal \n")); freecon(tty_con); return -1; } freecon(tty_con); } } level_s = optarg; break; default: fprintf(stderr, "%s\n", USAGE_STRING); return -1; } } /* Verify that the combination of command-line arguments are viable */ if (!(role_s || type_s || level_s)) { fprintf(stderr, "%s\n", USAGE_STRING); return -1; } /* Fill in a default type if one hasn't been specified. */ if (role_s && !type_s) { /* get_default_type() returns malloc'd memory */ if (get_default_type(role_s, &type_ptr)) { fprintf(stderr, _("Couldn't get default type.\n")); send_audit_message(0, old_context, new_con, ttyn); return -1; } type_s = type_ptr; } /* Create a temporary new context structure we extract and modify */ context = context_new(old_context); if (!context) { fprintf(stderr, _("failed to get new context.\n")); goto err_free; } /* Modify the temporary new context */ if (role_s) if (context_role_set(context, role_s)) { fprintf(stderr, _("failed to set new role %s\n"), role_s); goto err_free; } if (type_s) if (context_type_set(context, type_s)) { fprintf(stderr, _("failed to set new type %s\n"), type_s); goto err_free; } if (level_s) { range_ptr = build_new_range(level_s, context_range_get(context)); if (!range_ptr) { fprintf(stderr, _("failed to build new range with level %s\n"), level_s); goto err_free; } if (context_range_set(context, range_ptr)) { fprintf(stderr, _("failed to set new range %s\n"), range_ptr); goto err_free; } } /* Construct the final new context */ if (!(new_con = context_str(context))) { fprintf(stderr, _("failed to convert new context to string\n")); goto err_free; } if (security_check_context(new_con) < 0) { fprintf(stderr, _("%s is not a valid context\n"), new_con); send_audit_message(0, old_context, new_con, ttyn); goto err_free; } *new_context = strdup(new_con); if (!*new_context) { fprintf(stderr, _("Unable to allocate memory for new_context")); goto err_free; } free(type_ptr); free(range_ptr); context_free(context); return 0; err_free: free(type_ptr); free(range_ptr); /* Don't free new_con, context_free(context) handles this */ context_free(context); return -1; } /** * Take care of any signal setup */ static int set_signal_handles(void) { sigset_t empty; /* Empty the signal mask in case someone is blocking a signal */ if (sigemptyset(&empty)) { fprintf(stderr, _("Unable to obtain empty signal set\n")); return -1; } (void)sigprocmask(SIG_SETMASK, &empty, NULL); /* Terminate on SIGHUP. */ if (signal(SIGHUP, SIG_DFL) == SIG_ERR) { fprintf(stderr, _("Unable to set SIGHUP handler\n")); return -1; } return 0; } /************************************************************************ * * All code used for both PAM and shadow passwd goes in this section. * ************************************************************************/ int main(int argc, char *argv[]) { char *new_context = NULL; /* target security context */ char *old_context = NULL; /* original security context */ char *tty_context = NULL; /* current context of tty */ char *new_tty_context = NULL; /* new context of tty */ struct passwd pw; /* struct derived from passwd file line */ char *ttyn = NULL; /* tty path */ char **old_environ; int preserve_environment; int fd; pid_t childPid = 0; char *shell_argv0 = NULL; int rc; #ifdef USE_PAM int pam_status; /* pam return code */ pam_handle_t *pam_handle; /* opaque handle used by all PAM functions */ /* This is a jump table of functions for PAM to use when it wants to * * communicate with the user. We'll be using misc_conv(), which is * * provided for us via pam_misc.h. */ struct pam_conv pam_conversation = { misc_conv, NULL }; #endif /* * Step 0: Setup * * Do some initial setup, including dropping capabilities, checking * if it makes sense to continue to run newrole, and setting up * a scrubbed environment. */ if (drop_capabilities(FALSE)) { perror(_("Sorry, newrole failed to drop capabilities\n")); return -1; } if (set_signal_handles()) return -1; #ifdef USE_NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif old_environ = environ; environ = NULL; if (!is_selinux_enabled()) { fprintf(stderr, _("Sorry, newrole may be used only on " "a SELinux kernel.\n")); return -1; } if (security_getenforce() < 0) { fprintf(stderr, _("Could not determine enforcing mode.\n")); return -1; } /* * Step 1: Parse command line and valid arguments * * old_context and ttyn are required for audit logging, * context validation and pam */ if (getprevcon(&old_context)) { fprintf(stderr, _("failed to get old_context.\n")); return -1; } ttyn = ttyname(STDIN_FILENO); if (!ttyn || *ttyn == '\0') { fprintf(stderr, _("Warning! Could not retrieve tty information.\n")); } if (parse_command_line_arguments(argc, argv, ttyn, old_context, &new_context, &preserve_environment)) return -1; /* * Step 2: Authenticate the user. * * Re-authenticate the user running this program. * This is just to help confirm user intent (vs. invocation by * malicious software), not to authorize the operation (which is covered * by policy). Trusted path mechanism would be preferred. */ memset(&pw, 0, sizeof(pw)); if (extract_pw_data(&pw)) goto err_free; #ifdef USE_PAM if (read_pam_config()) { fprintf(stderr, _("error on reading PAM service configuration.\n")); goto err_free; } if (app_service_names != NULL && optind < argc) { if (strcmp(argv[optind], "-c") == 0 && optind < (argc - 1)) { /* * Check for a separate pam service name for the * command when invoked by newrole. */ char *cmd = NULL; rc = sscanf(argv[optind + 1], "%ms", &cmd); if (rc != EOF && cmd) { char *app_service_name = (char *)hashtab_search(app_service_names, cmd); free(cmd); if (app_service_name != NULL) service_name = app_service_name; } } } pam_status = pam_start(service_name, pw.pw_name, &pam_conversation, &pam_handle); if (pam_status != PAM_SUCCESS) { fprintf(stderr, _("failed to initialize PAM\n")); goto err_free; } if (!authenticate_via_pam(ttyn, pam_handle)) #else if (!authenticate_via_shadow_passwd(pw.pw_name)) #endif { fprintf(stderr, _("newrole: incorrect password for %s\n"), pw.pw_name); send_audit_message(0, old_context, new_context, ttyn); goto err_close_pam; } /* * Step 3: Handle relabeling of the tty. * * Once we authenticate the user, we know that we want to proceed with * the action. Prior to this point, no changes are made the to system. */ fd = relabel_tty(ttyn, new_context, &tty_context, &new_tty_context); if (fd < 0) goto err_close_pam; /* * Step 4: Fork * * Fork, allowing parent to clean up after shell has executed. * Child: reopen stdin, stdout, stderr and exec shell * Parnet: wait for child to die and restore tty's context */ childPid = fork(); if (childPid < 0) { /* fork failed, no child to worry about */ int errsv = errno; fprintf(stderr, _("newrole: failure forking: %s"), strerror(errsv)); if (restore_tty_label(fd, ttyn, tty_context, new_tty_context)) fprintf(stderr, _("Unable to restore tty label...\n")); if (close(fd)) fprintf(stderr, _("Failed to close tty properly\n")); goto err_close_pam; } else if (childPid) { /* PARENT * It doesn't make senes to exit early on errors at this point, * since we are doing cleanup which needs to be done. * We can exit with a bad rc though */ pid_t pid; int exit_code = 0; int status; do { pid = wait(&status); } while (pid < 0 && errno == EINTR); /* Preserve child exit status, unless there is another error. */ if (WIFEXITED(status)) exit_code = WEXITSTATUS(status); if (restore_tty_label(fd, ttyn, tty_context, new_tty_context)) { fprintf(stderr, _("Unable to restore tty label...\n")); exit_code = -1; } freecon(tty_context); freecon(new_tty_context); if (close(fd)) { fprintf(stderr, _("Failed to close tty properly\n")); exit_code = -1; } #ifdef USE_PAM #ifdef NAMESPACE_PRIV pam_status = pam_close_session(pam_handle, 0); if (pam_status != PAM_SUCCESS) { fprintf(stderr, "pam_close_session failed with %s\n", pam_strerror(pam_handle, pam_status)); exit_code = -1; } #endif rc = pam_end(pam_handle, pam_status); if (rc != PAM_SUCCESS) { fprintf(stderr, "pam_end failed with %s\n", pam_strerror(pam_handle, rc)); exit_code = -1; } hashtab_map(app_service_names, free_hashtab_entry, NULL); hashtab_destroy(app_service_names); #endif free(pw.pw_name); free(pw.pw_dir); free(pw.pw_shell); free(shell_argv0); free(new_context); return exit_code; } /* CHILD */ /* Close the tty and reopen descriptors 0 through 2 */ if (ttyn) { if (close(fd) || close(0) || close(1) || close(2)) { fprintf(stderr, _("Could not close descriptors.\n")); goto err_close_pam; } fd = open(ttyn, O_RDWR | O_NONBLOCK); if (fd != 0) goto err_close_pam; rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); if (rc) goto err_close_pam; fd = open(ttyn, O_RDWR | O_NONBLOCK); if (fd != 1) goto err_close_pam; rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); if (rc) goto err_close_pam; fd = open(ttyn, O_RDWR | O_NONBLOCK); if (fd != 2) goto err_close_pam; rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); if (rc) goto err_close_pam; } /* * Step 5: Execute a new shell with the new context in `new_context'. * * Establish context, namesapce and any options for the new shell */ if (optind < 1) optind = 1; /* This is ugly, but use newrole's argv for the exec'd shells argv */ if (asprintf(&shell_argv0, "-%s", pw.pw_shell) < 0) { fprintf(stderr, _("Error allocating shell's argv0.\n")); shell_argv0 = NULL; goto err_close_pam; } argv[optind - 1] = shell_argv0; if (setexeccon(new_context)) { fprintf(stderr, _("Could not set exec context to %s.\n"), new_context); goto err_close_pam; } #ifdef NAMESPACE_PRIV /* Ask PAM to setup session for user running this program */ pam_status = pam_open_session(pam_handle, 0); if (pam_status != PAM_SUCCESS) { fprintf(stderr, "pam_open_session failed with %s\n", pam_strerror(pam_handle, pam_status)); goto err_close_pam; } #endif if (send_audit_message(1, old_context, new_context, ttyn)) { fprintf(stderr, _("Failed to send audit message")); goto err_close_pam_session; } freecon(old_context); old_context=NULL; freecon(new_context); new_context=NULL; #ifdef NAMESPACE_PRIV if (transition_to_caller_uid()) { fprintf(stderr, _("Failed to transition to namespace\n")); goto err_close_pam_session; } #endif if (drop_capabilities(TRUE)) { fprintf(stderr, _("Failed to drop capabilities %m\n")); goto err_close_pam_session; } /* Handle environment changes */ if (restore_environment(preserve_environment, old_environ, &pw)) { fprintf(stderr, _("Unable to restore the environment, " "aborting\n")); goto err_close_pam_session; } execv(pw.pw_shell, argv + optind - 1); /* * Error path cleanup * * If we reach here, then we failed to exec the new shell. */ perror(_("failed to exec shell\n")); err_close_pam_session: #ifdef NAMESPACE_PRIV pam_status = pam_close_session(pam_handle, 0); if (pam_status != PAM_SUCCESS) fprintf(stderr, "pam_close_session failed with %s\n", pam_strerror(pam_handle, pam_status)); #endif err_close_pam: #ifdef USE_PAM rc = pam_end(pam_handle, pam_status); if (rc != PAM_SUCCESS) fprintf(stderr, "pam_end failed with %s\n", pam_strerror(pam_handle, rc)); #endif err_free: freecon(tty_context); freecon(new_tty_context); freecon(old_context); freecon(new_context); free(pw.pw_name); free(pw.pw_dir); free(pw.pw_shell); free(shell_argv0); #ifdef USE_PAM if (app_service_names) { hashtab_map(app_service_names, free_hashtab_entry, NULL); hashtab_destroy(app_service_names); } #endif return -1; } /* main() */ policycoreutils-3.3/newrole/newrole.pamd000066400000000000000000000004331413427467300206140ustar00rootroot00000000000000#%PAM-1.0 # Uncomment the next line if you do not want to enter your passwd everytime # auth sufficient pam_rootok.so auth include system-auth account include system-auth password include system-auth session include system-auth session optional pam_xauth.so policycoreutils-3.3/newrole/ru/000077500000000000000000000000001413427467300167245ustar00rootroot00000000000000policycoreutils-3.3/newrole/ru/newrole.1000066400000000000000000000115371413427467300204700ustar00rootroot00000000000000.TH NEWROLE "1" "Октябрь 2000" "Security Enhanced Linux" NSA .SH ИМЯ newrole \- запустить оболочку с новой ролью SELinux .SH ОБЗОР .B newrole [\fB-r\fR|\fB--role\fR] \fIROLE\fR [\fB-t\fR|\fB--type\fR] \fITYPE\fR [\fB-l\fR|\fB--level\fR] [\fB-p\fR|\fB--preserve-environment\fR] \fILEVEL\fR [-- [\fIARGS\fR]...] .SH ОПИСАНИЕ .PP Запустить новую оболочку в новом контексте. Новый контекст берётся из старого контекста, в котором изначально исполнялась .B newrole. Если указан параметр .B -r или .B --role , новый контекст будет иметь роль, заданную \fIROLE\fR. Если указан параметр .B -t или .B --type , новый контекст будет иметь тип (домен), заданный \fITYPE\fR. Если указана роль, но не указан тип, тип по умолчанию берётся из указанной роли. Если указан параметр .B -l или .B --level , новый контекст будет иметь уровень конфиденциальности, заданный \fILEVEL\fR. Если \fILEVEL\fR является диапазоном, новый контекст будет иметь уровень конфиденциальности и допуск, заданные этим диапазоном. Если указан параметр .B -p или .B --preserve-environment , оболочка с новым контекстом SELinux сохранит переменные среды, в ином случае будет создана новая минимальная среда. .PP Дополнительные аргументы .I ARGS могут присутствовать после параметра --, в этом случае они передаются в новую оболочку. В частности, при использовании аргумента \-\- \-c следующий аргумент будет обрабатываться как команда большинством интерпретаторов команд. .PP Если для newrole указан аргумент команды и имя команды найдено в /etc/selinux/newrole_pam.conf, будет использована служба pam, указанная в этом файле для команды, а не обычная конфигурация pam для newrole. Это позволяет устанавливать конфигурацию pam для каждой команды при вызове через newrole, например, чтобы пропустить этап интерактивной повторной аутентификации. .PP Новой оболочкой будет оболочка, указанная в записи пользователя в файле .I /etc/passwd. .PP .B -V или .B --version показывает текущую версию newrole .PP .SH ПРИМЕР .br Смена роли: # id \-Z staff_u:staff_r:staff_t:SystemLow-SystemHigh # newrole \-r sysadm_r # id \-Z staff_u:sysadm_r:sysadm_t:SystemLow-SystemHigh Смена только уровня конфиденциальности: # id \-Z staff_u:sysadm_r:sysadm_t:Unclassified-SystemHigh # newrole \-l Secret # id \-Z staff_u:sysadm_r:sysadm_t:Secret-SystemHigh .PP Смена уровня конфиденциальности и допуска: # id \-Z staff_u:sysadm_r:sysadm_t:Unclassified-SystemHigh # newrole \-l Secret-Secret # id \-Z staff_u:sysadm_r:sysadm_t:Secret .PP Запуск программы с указанной ролью или уровнем: # newrole \-r sysadm_r \-\- \-c "/path/to/app arg1 arg2..." # newrole \-l Secret \-\- \-c "/path/to/app arg1 arg2..." .SH ФАЙЛЫ /etc/passwd - информация об учётных записях пользователей .br /etc/shadow - зашифрованные пароли и информация об устаревании паролей .br /etc/selinux//contexts/default_type - типы по умолчанию для ролей .br /etc/selinux//contexts/securetty_types - типы securetty для изменений уровня .br /etc/selinux/newrole_pam.conf - необязательное сопоставление команд с отдельными службами pam .br .SH СМОТРИТЕ ТАКЖЕ .BR runcon (1) .SH АВТОРЫ .nf Anthony Colatrella Tim Fraser Steve Grubb Darrel Goeddel Michael Thompson Dan Walsh Перевод на русский язык выполнила Герасименко Олеся policycoreutils-3.3/po/000077500000000000000000000000001413427467300152415ustar00rootroot00000000000000policycoreutils-3.3/po/Makefile000066400000000000000000000076361413427467300167150ustar00rootroot00000000000000# # Makefile for the PO files (translation) catalog # PREFIX ?= /usr TOP = ../.. # What is this package? NLSPACKAGE = policycoreutils POTFILE = $(NLSPACKAGE).pot INSTALL = /usr/bin/install -c -p INSTALL_DATA = $(INSTALL) -m 644 INSTALL_DIR = /usr/bin/install -d # destination directory INSTALL_NLS_DIR = $(PREFIX)/share/locale # PO catalog handling MSGMERGE = msgmerge MSGMERGE_FLAGS = -q XGETTEXT = xgettext --default-domain=$(NLSPACKAGE) MSGFMT = msgfmt # All possible linguas PO_LINGUAS := $(sort $(patsubst %.po,%,$(wildcard *.po))) # Only the files matching what the user has set in LINGUAS USER_LINGUAS := $(filter $(patsubst %,%%,$(LINGUAS)),$(PO_LINGUAS)) # if no valid LINGUAS, build all languages USE_LINGUAS := $(if $(USER_LINGUAS),$(USER_LINGUAS),$(PO_LINGUAS)) POFILES = $(patsubst %,%.po,$(USE_LINGUAS)) MOFILES = $(patsubst %.po,%.mo,$(POFILES)) POTFILES = \ ../run_init/open_init_pty.c \ ../run_init/run_init.c \ ../semodule_link/semodule_link.c \ ../audit2allow/audit2allow \ ../semanage/seobject.py \ ../setsebool/setsebool.c \ ../newrole/newrole.c \ ../load_policy/load_policy.c \ ../sestatus/sestatus.c \ ../semodule/semodule.c \ ../setfiles/setfiles.c \ ../semodule_package/semodule_package.c \ ../semodule_deps/semodule_deps.c \ ../semodule_expand/semodule_expand.c \ ../scripts/chcat \ ../scripts/fixfiles \ ../restorecond/stringslist.c \ ../restorecond/restorecond.h \ ../restorecond/utmpwatcher.h \ ../restorecond/stringslist.h \ ../restorecond/restorecond.c \ ../restorecond/utmpwatcher.c \ ../gui/booleansPage.py \ ../gui/fcontextPage.py \ ../gui/loginsPage.py \ ../gui/mappingsPage.py \ ../gui/modulesPage.py \ ../gui/polgen.glade \ ../gui/polgengui.py \ ../gui/portsPage.py \ ../gui/semanagePage.py \ ../gui/statusPage.py \ ../gui/system-config-selinux.glade \ ../gui/system-config-selinux.py \ ../gui/usersPage.py \ ../secon/secon.c \ booleans.py \ ../sepolicy/sepolicy.py \ ../sepolicy/sepolicy/communicate.py \ ../sepolicy/sepolicy/__init__.py \ ../sepolicy/sepolicy/network.py \ ../sepolicy/sepolicy/generate.py \ ../sepolicy/sepolicy/sepolicy.glade \ ../sepolicy/sepolicy/gui.py \ ../sepolicy/sepolicy/manpage.py \ ../sepolicy/sepolicy/transition.py \ ../sepolicy/sepolicy/templates/executable.py \ ../sepolicy/sepolicy/templates/__init__.py \ ../sepolicy/sepolicy/templates/network.py \ ../sepolicy/sepolicy/templates/rw.py \ ../sepolicy/sepolicy/templates/script.py \ ../sepolicy/sepolicy/templates/semodule.py \ ../sepolicy/sepolicy/templates/tmp.py \ ../sepolicy/sepolicy/templates/user.py \ ../sepolicy/sepolicy/templates/var_lib.py \ ../sepolicy/sepolicy/templates/var_log.py \ ../sepolicy/sepolicy/templates/var_run.py \ ../sepolicy/sepolicy/templates/var_spool.py #default:: clean all:: $(MOFILES) booleans.py: sepolicy booleans -a > booleans.py $(POTFILE): $(POTFILES) booleans.py $(XGETTEXT) --keyword=_ --keyword=N_ $(POTFILES) @if cmp -s $(NLSPACKAGE).po $(POTFILE); then \ rm -f $(NLSPACKAGE).po; \ else \ mv -f $(NLSPACKAGE).po $(POTFILE); \ fi; \ update-po: Makefile $(POTFILE) refresh-po @rm -f booleans.py refresh-po: Makefile for cat in $(POFILES); do \ lang=`basename $$cat .po`; \ if $(MSGMERGE) $(MSGMERGE_FLAGS) $$lang.po $(POTFILE) > $$lang.pot ; then \ mv -f $$lang.pot $$lang.po ; \ echo "$(MSGMERGE) of $$lang succeeded" ; \ else \ echo "$(MSGMERGE) of $$lang failed" ; \ rm -f $$lang.pot ; \ fi \ done clean: @rm -fv *mo *~ .depend @rm -rf tmp install: $(MOFILES) @for n in $(MOFILES); do \ l=`basename $$n .mo`; \ $(INSTALL_DIR) $(DESTDIR)$(INSTALL_NLS_DIR)/$$l/LC_MESSAGES; \ $(INSTALL_DATA) --verbose $$n $(DESTDIR)$(INSTALL_NLS_DIR)/$$l/LC_MESSAGES/$(NLSPACKAGE).mo; \ done %.mo: %.po $(MSGFMT) -o $@ $< report: @for cat in $(wildcard *.po); do \ echo -n "$$cat: "; \ msgfmt -v --statistics -o /dev/null $$cat; \ done .PHONY: missing depend relabel: policycoreutils-3.3/po/af.po000066400000000000000000003462541413427467300162050ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: msgid "" msgstr "" "Project-Id-Version: Policycoreutils\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-10-10 16:04-0400\n" "PO-Revision-Date: 2012-03-30 18:14+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Afrikaans (http://www.transifex.com/projects/p/fedora/" "language/af/)\n" "Language: af\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../run_init/run_init.c:67 msgid "" "USAGE: run_init