diff --git a/policycoreutils/Makefile b/policycoreutils/Makefile index 3980799..6624804 100644 --- a/policycoreutils/Makefile +++ b/policycoreutils/Makefile @@ -1,4 +1,4 @@ -SUBDIRS = sepolicy setfiles semanage load_policy newrole run_init sandbox secon audit2allow audit2why sestatus semodule_package semodule semodule_link semodule_expand semodule_deps sepolgen-ifgen setsebool scripts po man gui +SUBDIRS = sepolicy setfiles semanage semanage/default_encoding load_policy newrole run_init sandbox secon audit2allow sestatus semodule_package semodule semodule_link semodule_expand semodule_deps sepolgen-ifgen setsebool scripts po man gui INOTIFYH = $(shell ls /usr/include/sys/inotify.h 2>/dev/null) diff --git a/policycoreutils/audit2allow/Makefile b/policycoreutils/audit2allow/Makefile index 88635d4..fc290ea 100644 --- a/policycoreutils/audit2allow/Makefile +++ b/policycoreutils/audit2allow/Makefile @@ -5,14 +5,19 @@ LIBDIR ?= $(PREFIX)/lib MANDIR ?= $(PREFIX)/share/man LOCALEDIR ?= /usr/share/locale -all: ; +all: audit2why + +audit2why: + ln -sf audit2allow audit2why install: all -mkdir -p $(BINDIR) install -m 755 audit2allow $(BINDIR) + (cd $(BINDIR); ln -sf audit2allow audit2why) install -m 755 sepolgen-ifgen $(BINDIR) -mkdir -p $(MANDIR)/man1 install -m 644 audit2allow.1 $(MANDIR)/man1/ + install -m 644 audit2why.1 $(MANDIR)/man1/ clean: rm -f *~ diff --git a/policycoreutils/audit2allow/audit2allow b/policycoreutils/audit2allow/audit2allow index 8e0c396..9bd66f5 100644 --- a/policycoreutils/audit2allow/audit2allow +++ b/policycoreutils/audit2allow/audit2allow @@ -18,7 +18,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -import sys +import sys, os import sepolgen.audit as audit import sepolgen.policygen as policygen @@ -29,6 +29,8 @@ import sepolgen.defaults as defaults import sepolgen.module as module from sepolgen.sepolgeni18n import _ import selinux.audit2why as audit2why +import locale +locale.setlocale(locale.LC_ALL, '') class AuditToPolicy: VERSION = "%prog .1" @@ -80,8 +82,7 @@ class AuditToPolicy: parser.add_option("--interface-info", dest="interface_info", help="file name of interface information") parser.add_option("--debug", dest="debug", action="store_true", default=False, help="leave generated modules for -M") - - parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=False, + parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=(os.path.basename(sys.argv[0])=="audit2why"), help="Translates SELinux audit messages into a description of why the access was denied") options, args = parser.parse_args() diff --git a/policycoreutils/audit2allow/audit2why.1 b/policycoreutils/audit2allow/audit2why.1 new file mode 100644 index 0000000..a9e8893 --- /dev/null +++ b/policycoreutils/audit2allow/audit2why.1 @@ -0,0 +1 @@ +.so man1/audit2allow.1 diff --git a/policycoreutils/audit2why/Makefile b/policycoreutils/audit2why/Makefile deleted file mode 100644 index 63eb8b3..0000000 --- a/policycoreutils/audit2why/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# Installation directories. -PREFIX ?= $(DESTDIR)/usr -BINDIR ?= $(PREFIX)/bin -MANDIR ?= $(PREFIX)/share/man - -TARGETS=audit2why - -all: $(TARGETS) - -install: all - -mkdir -p $(BINDIR) - install -m 755 $(TARGETS) $(BINDIR) - -mkdir -p $(MANDIR)/man1 - install -m 644 audit2why.1 $(MANDIR)/man1/ - -clean: - -relabel: diff --git a/policycoreutils/audit2why/audit2why b/policycoreutils/audit2why/audit2why deleted file mode 100644 index 21a72aa..0000000 --- a/policycoreutils/audit2why/audit2why +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -/usr/bin/audit2allow -w $* diff --git a/policycoreutils/audit2why/audit2why.1 b/policycoreutils/audit2why/audit2why.1 deleted file mode 100644 index a9e8893..0000000 --- a/policycoreutils/audit2why/audit2why.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/audit2allow.1 diff --git a/policycoreutils/gui/Makefile b/policycoreutils/gui/Makefile index b5abbb9..513f2c4 100644 --- a/policycoreutils/gui/Makefile +++ b/policycoreutils/gui/Makefile @@ -1,7 +1,9 @@ # Installation directories. PREFIX ?= ${DESTDIR}/usr +SYSCONFDIR ?= ${DESTDIR}/etc BINDIR ?= $(PREFIX)/bin SHAREDIR ?= $(PREFIX)/share/system-config-selinux +DATADIR ?= $(PREFIX)/share TARGETS= \ booleansPage.py \ @@ -16,6 +18,7 @@ portsPage.py \ semanagePage.py \ statusPage.py \ system-config-selinux.glade \ +system-config-selinux.png \ usersPage.py all: $(TARGETS) system-config-selinux.py polgengui.py @@ -23,11 +26,19 @@ all: $(TARGETS) system-config-selinux.py polgengui.py install: all -mkdir -p $(SHAREDIR) -mkdir -p $(BINDIR) + -mkdir -p $(DATADIR)/pixmaps + -mkdir -p $(DATADIR)/icons/hicolor/24x24/apps + -mkdir -p $(SYSCONFDIR) + -mkdir -p $(DATADIR)/polkit-1/actions/ install -m 755 system-config-selinux.py $(SHAREDIR) + install -m 755 system-config-selinux $(BINDIR) install -m 755 polgengui.py $(SHAREDIR) - install -m 755 sepolgen $(BINDIR) install -m 644 $(TARGETS) $(SHAREDIR) - + install -m 644 system-config-selinux.png $(DATADIR)/pixmaps + install -m 644 system-config-selinux.png $(DATADIR)/icons/hicolor/24x24/apps + install -m 644 system-config-selinux.png $(DATADIR)/system-config-selinux + install -m 644 *.desktop $(DATADIR)/system-config-selinux + install -m 644 org.fedoraproject.config.selinux.policy $(DATADIR)/polkit-1/actions/ clean: indent: diff --git a/policycoreutils/gui/org.fedoraproject.config.selinux.policy b/policycoreutils/gui/org.fedoraproject.config.selinux.policy new file mode 100644 index 0000000..fcfa81d --- /dev/null +++ b/policycoreutils/gui/org.fedoraproject.config.selinux.policy @@ -0,0 +1,22 @@ + + + + + System Config SELinux + http://fedorahosted.org/system-config-selinux + + + Run System Config SELinux + Authentication is required to run system-config-selinux + system-selinux + + no + no + auth_admin + + /usr/share/system-config-selinux/system-config-selinux.py + true + + diff --git a/policycoreutils/gui/selinux-polgengui.desktop b/policycoreutils/gui/selinux-polgengui.desktop new file mode 100644 index 0000000..0c2f399 --- /dev/null +++ b/policycoreutils/gui/selinux-polgengui.desktop @@ -0,0 +1,67 @@ +[Desktop Entry] +Name=SELinux Policy Generation Tool +Name[bn_IN]=SELinux Policy নির্মাণের সামগ্রী +Name[ca]=Eina de generació de polítiques del SELinux +Name[da]=Regelsætgenereringsværktøj til SELinux +Name[de]=Tool zur Erstellung von SELinux-Richtlinien +Name[es]=Generador de Políticas de SELinux +Name[fi]=SELinux-käytäntöjen generointityökalu +Name[fr]=Outil de génération de stratégies SELinux +Name[gu]=SELinux પોલિસી બનાવટ સાધન +Name[hi]=SELinux पॉलिसी जनन औजार +Name[it]=Tool di generazione della policy di SELinux +Name[ja]=SELinux ポリシー生成ツール +Name[kn]=SELinux ಪಾಲಿಸಿ ಉತ್ಪಾದನಾ ಉಪಕರಣ +Name[ko]=SELinux 정책 생성 도구 +Name[ml]=SELinux പോളിസി ഉത്പാദന പ്രയോഗം +Name[mr]=SELinux करार निर्माण साधन +Name[nl]=SELinux tactiek generatie gereedschap +Name[or]=SELinux ନୀତି ସୃଷ୍ଟି ଉପକରଣ +Name[pa]=SELinux ਪਾਲਿਸੀ ਨਿਰਮਾਣ ਜੰਤਰ +Name[pl]=Narzędzie tworzenia polityki SELinuksa +Name[pt]=Ferramenta de Geração de Políticas SELinux +Name[pt_BR]=Ferramenta de criação de políticas do SELinux +Name[ru]=Средство создания политики SELinux +Name[sv]=Genereringsverktyg för SELinuxpolicy +Name[ta]=SELinux பாலிசி உற்பத்தி கருவி +Name[te]=SELinux నిర్వహణ +Name[uk]=Утиліта генерації правил SELinux +Name[zh_CN]=SELinux 策略生成工具 +Name[zh_TW]=SELinux 政策產生工具(SELinux Policy Generation Tool) +Comment=Generate SELinux policy modules +Comment[bn_IN]=SELinux নিয়মনীতির মডিউল নির্মাণ করুন +Comment[ca]=Genera els mòduls de les polítiques de SELinux +Comment[da]=Generér SELinux-regelsætmodul +Comment[de]=Tool zur Erstellung von SELinux-Richtlinien +Comment[es]=Generar módulos de política de SELinux +Comment[fi]=Generoi SELinuxin käytäntömoduuleja +Comment[fr]=Génére des modules de stratégie SELinux +Comment[gu]=SELinux પોલિસી મોડ્યુલોને ઉત્પન્ન કરો +Comment[hi]=नया पॉलिसी मॉड्यूल उत्पन्न करें +Comment[it]=Genera moduli della politica di SELinux +Comment[ja]=新しいポリシーモジュールの作成 +Comment[kn]=SELinux ಪಾಲಿಸಿ ಘಟಕಗಳನ್ನು ಉತ್ಪಾದಿಸು +Comment[ko]=SELinux 정책 모듈 생성 +Comment[ml]=SELinux യ പോളിസി ഘങ്ങള്‍ തയ്യാറാക്കുക +Comment[mr]=SELinux करार घटके निर्माण करा +Comment[nl]=Maak een SELinux tactiek module aan +Comment[or]=SELinux ନୀତି ଏକକାଂଶ ସୃଷ୍ଟିକରନ୍ତୁ +Comment[pa]=SELinux ਪਾਲਿਸੀ ਮੈਡਿਊਲ ਬਣਾਓ +Comment[pl]=Tworzenie nowych modułów polityki SELinuksa +Comment[pt]=Gerar módulos de políticas SELinux +Comment[pt_BR]=Gerar módulos de política do SELinux +Comment[ru]=Генерация модулей политики SELinux +Comment[sv]=Generera SELinux-policymoduler +Comment[ta]=SELinux கொள்கை தொகுதியை உருவாக்கவும் +Comment[te]=SELinux పాలసీ మాడ్యూళ్ళను వుద్భవింపచేయుము +Comment[uk]=Створення модулів контролю доступу SELinux +Comment[zh_CN]=生成 SELinux 策略模块 +Comment[zh_TW]=產生 SELinux 政策模組 +StartupNotify=true +Icon=system-config-selinux +Exec=/usr/bin/selinux-polgengui +Type=Application +Terminal=false +Categories=System;Security; +X-Desktop-File-Install-Version=0.2 +Keywords=policy;security;selinux;avc;permission;mac; diff --git a/policycoreutils/gui/sepolgen b/policycoreutils/gui/sepolgen deleted file mode 100644 index 2f0c1cc..0000000 --- a/policycoreutils/gui/sepolgen +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -sepolicy generate $* diff --git a/policycoreutils/gui/system-config-selinux b/policycoreutils/gui/system-config-selinux new file mode 100755 index 0000000..5be5ccd --- /dev/null +++ b/policycoreutils/gui/system-config-selinux @@ -0,0 +1,3 @@ +#!/bin/sh + +exec /usr/bin/pkexec /usr/share/system-config-selinux/system-config-selinux.py diff --git a/policycoreutils/gui/system-config-selinux.desktop b/policycoreutils/gui/system-config-selinux.desktop new file mode 100644 index 0000000..8822ce2 --- /dev/null +++ b/policycoreutils/gui/system-config-selinux.desktop @@ -0,0 +1,67 @@ +[Desktop Entry] +Name=SELinux Management +Name[bn_IN]=SELinux পরিচালনা +Name[da]=Håndtering af SELinux +Name[de]=SELinux-Management +Name[ca]=Gestió de SELinux +Name[es]=Administración de SELinux +Name[fi]=SELinuxin ylläpito +Name[fr]=Gestion de SELinux +Name[gu]=SELinux સંચાલન +Name[hi]=SELinux प्रबंधन +Name[jp]=SELinux 管理 +Name[it]=Gestione di SELinux +Name[kn]=SELinux ವ್ಯವಸ್ಥಾಪನೆ +Name[ko]=SELinux 관리 +Name[ml]=SELinux മാനേജ്മെന്റ് +Name[mr]=SELinux मॅनेजमेंट +Name[nl]=SELinux beheer +Name[or]=SELinux ପରିଚାଳନା +Name[pa]=SELinux ਮੈਨੇਜਮੈਂਟ +Name[pl]=Zarządzanie SELinuksem +Name[pt_BR]=Gerenciamento do SELinux +Name[pt]=Gestão de SELinux +Name[ru]=Управление SELinux +Name[sv]=SELinux-hantering +Name[ta]=SELinux மேலாண்மை +Name[te]=SELinux నిర్వహణ +Name[uk]=Керування SELinux +Name[zh_CN]=SELinux 管理 +Name[zh_TW]=SELinux 管理 +Comment=Configure SELinux in a graphical setting +Comment[bn_IN]=গ্রাফিক্যাল পরিবেশে SELinux কনফিগার করুন +Comment[ca]=Configura SELinuc an mode de preferències gràfiques +Comment[da]=Konfigurér SELinux i et grafisk miljø +Comment[de]=SELinux in einer grafischen Einstellung konfigurieren +Comment[es]=Defina SELinux en una configuración de interfaz gráfica +Comment[fi]=Tee SELinuxin asetukset graafisesti +Comment[fr]=Configure SELinux dans un environnement graphique +Comment[gu]=ગ્રાફિકલ સુયોજનમાં SELinux ને રૂપરેખાંકિત કરો +Comment[hi]=SELinux को आलेखी सेटिंग में विन्यस्त करें +Comment[it]=Configura SELinux in una impostazione grafica +Comment[jp]=グラフィカルな設定画面で SELinux を設定する +Comment[ko]=SELinux를 그래픽 사용자 인터페이스로 설정 +Comment[kn]=SELinux ಅನ್ನು ಒಂದು ಚಿತ್ರಾತ್ಮಕ ಸಿದ್ದತೆಯಲ್ಲಿ ಸಂರಚಿಸಿ +Comment[ml]=ഒരു ഗ്രാഫിക്കല്‍ സജ്ജീകരണത്തില്‍ SELinux ക്രമീകരിയ്ക്കുക +Comment[mr]=ग्राफिकल सेटिंगमध्ये SELinux संरचीत करा +Comment[nl]=Configureer SELinux in een grafische omgeving +Comment[or]=SELinux କୁ ଆଲେଖିକ ସଂରଚନାରେ ବିନ୍ୟାସ କରନ୍ତୁ +Comment[pa]=SELinux ਨੂੰ ਗਰਾਫੀਕਲ ਸੈਟਿੰਗ ਵਿੱਚ ਸੰਰਚਿਤ ਕਰੋ +Comment[pl]=Konfiguracja SELinuksa w trybie graficznym +Comment[pt]=Configurar o SELinux num ambiente gráfico +Comment[pt_BR]=Configure o SELinux em uma configuração gráfica +Comment[ru]=Настройка SELinux в графическом режиме +Comment[sv]=Konfigurera SELinux i en grafisk miljö +Comment[ta]=SELinuxஐ ஒரு வரைகலை அமைவில் கட்டமைக்கவும் +Comment[te]=SELinuxను గ్రాఫికల్ అమర్పునందు ఆకృతీకరించుము +Comment[uk]=Засіб для налаштування SELinux з графічним інтерфейсом +Comment[zh_CN]=在图形设置中配置 SELinux +Comment[zh_TW]=在圖形話設定中配置 SELinux +StartupNotify=true +Icon=system-config-selinux +Exec=/usr/bin/system-config-selinux +Type=Application +Terminal=false +Categories=System;Security; +X-Desktop-File-Install-Version=0.2 +Keywords=policy;security;selinux;avc;permission;mac; diff --git a/policycoreutils/gui/system-config-selinux.png b/policycoreutils/gui/system-config-selinux.png new file mode 100644 index 0000000..68ffcb7 Binary files /dev/null and b/policycoreutils/gui/system-config-selinux.png differ diff --git a/policycoreutils/newrole/newrole.c b/policycoreutils/newrole/newrole.c index 8fbf2d0..3510f12 100644 --- a/policycoreutils/newrole/newrole.c +++ b/policycoreutils/newrole/newrole.c @@ -576,19 +576,22 @@ static int drop_capabilities(int full) */ static int drop_capabilities(int full) { + uid_t uid = getuid(); + if (!uid) return 0; + capng_setpid(getpid()); capng_clear(CAPNG_SELECT_BOTH); if (capng_lock() < 0) return -1; - uid_t uid = getuid(); /* Change uid */ if (setresuid(uid, uid, uid)) { fprintf(stderr, _("Error changing uid, aborting.\n")); return -1; } if (! full) - capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SYS_ADMIN , CAP_FOWNER , CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_SETPCAP, -1); + capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SYS_ADMIN , CAP_FOWNER , CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_SETPCAP, CAP_AUDIT_WRITE, -1); + return capng_apply(CAPNG_SELECT_BOTH); } @@ -680,7 +683,7 @@ static int relabel_tty(const char *ttyn, security_context_t new_context, security_context_t * tty_context, security_context_t * new_tty_context) { - int fd; + int fd, rc; int enforcing = security_getenforce(); security_context_t tty_con = NULL; security_context_t new_tty_con = NULL; @@ -699,7 +702,13 @@ static int relabel_tty(const char *ttyn, security_context_t new_context, fprintf(stderr, _("Error! Could not open %s.\n"), ttyn); return fd; } - fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); + /* this craziness is to make sure we cann'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 " @@ -1010,9 +1019,9 @@ int main(int argc, char *argv[]) int fd; pid_t childPid = 0; char *shell_argv0 = NULL; + int rc; #ifdef USE_PAM - int rc; int pam_status; /* pam return code */ pam_handle_t *pam_handle; /* opaque handle used by all PAM functions */ @@ -1226,15 +1235,23 @@ int main(int argc, char *argv[]) fd = open(ttyn, O_RDONLY | O_NONBLOCK); if (fd != 0) goto err_close_pam; - fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); + 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; - fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); + 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; - fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); + rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); + if (rc) + goto err_close_pam; } /* diff --git a/policycoreutils/newrole/newrole.pamd b/policycoreutils/newrole/newrole.pamd index d1b435c..de3582f 100644 --- a/policycoreutils/newrole/newrole.pamd +++ b/policycoreutils/newrole/newrole.pamd @@ -1,4 +1,6 @@ #%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 diff --git a/policycoreutils/po/Makefile b/policycoreutils/po/Makefile index a377996..9c1486e 100644 --- a/policycoreutils/po/Makefile +++ b/policycoreutils/po/Makefile @@ -81,12 +81,16 @@ POTFILES = \ ../sepolicy/sepolicy/templates/var_log.py \ ../sepolicy/sepolicy/templates/var_run.py \ ../sepolicy/sepolicy/templates/var_spool.py \ + booleans.py #default:: clean all:: $(MOFILES) -$(POTFILE): $(POTFILES) +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; \ @@ -95,6 +99,7 @@ $(POTFILE): $(POTFILES) fi; \ update-po: Makefile $(POTFILE) refresh-po + @rm -f booleans.py refresh-po: Makefile for cat in $(POFILES); do \ diff --git a/policycoreutils/po/ja.po b/policycoreutils/po/ja.po index 72ae12d..649d288 100644 --- a/policycoreutils/po/ja.po +++ b/policycoreutils/po/ja.po @@ -9,14 +9,14 @@ # , 2012. # Noriko Mizumoto , 2006, 2008, 2009. # Takuro Nagamoto , 2006. -# Tomoyuki KATO , 2012. +# Tomoyuki KATO , 2012-2013. msgid "" msgstr "" "Project-Id-Version: Policycoreutils\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-01-04 12:01-0500\n" -"PO-Revision-Date: 2013-01-04 17:02+0000\n" -"Last-Translator: dwalsh \n" +"PO-Revision-Date: 2013-02-14 03:32+0000\n" +"Last-Translator: Tomoyuki KATO \n" "Language-Team: Japanese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -292,7 +292,7 @@ msgstr "MLS/MCS 範囲" #: ../semanage/seobject.py:672 msgid "Service" -msgstr "" +msgstr "サービス" #: ../semanage/seobject.py:698 ../semanage/seobject.py:729 #: ../semanage/seobject.py:796 ../semanage/seobject.py:853 @@ -429,7 +429,7 @@ msgstr "タイプが必要です" #: ../semanage/seobject.py:1814 #, python-format msgid "Type %s is invalid, must be a port type" -msgstr "" +msgstr "形式 %s が無効です、ポート形式である必要があります" #: ../semanage/seobject.py:1000 ../semanage/seobject.py:1062 #: ../semanage/seobject.py:1117 ../semanage/seobject.py:1123 @@ -551,12 +551,12 @@ msgstr "不明又は欠如したプロトコル" #: ../semanage/seobject.py:1256 msgid "SELinux node type is required" -msgstr "" +msgstr "SELinux ノード形式が必要です" #: ../semanage/seobject.py:1259 ../semanage/seobject.py:1327 #, python-format msgid "Type %s is invalid, must be a node type" -msgstr "" +msgstr "形式 %s が無効です、ノード形式である必要があります" #: ../semanage/seobject.py:1263 ../semanage/seobject.py:1331 #: ../semanage/seobject.py:1367 ../semanage/seobject.py:1465 @@ -790,7 +790,7 @@ msgstr "ファイル仕様 %s は、等価規則 '%s %s' と競合します; 代 #: ../semanage/seobject.py:1755 #, python-format msgid "Type %s is invalid, must be a file or device type" -msgstr "" +msgstr "形式 %s が無効です、ファイルまたはデバイス形式である必要があります" #: ../semanage/seobject.py:1763 ../semanage/seobject.py:1768 #: ../semanage/seobject.py:1824 ../semanage/seobject.py:1906 @@ -2178,11 +2178,11 @@ msgstr "生成された SELinux の man ページの格納先となるパス" #: ../sepolicy/sepolicy.py:207 msgid "name of the OS for man pages" -msgstr "" +msgstr "マニュアルページ向け OS 名称" #: ../sepolicy/sepolicy.py:209 msgid "Generate HTML man pages structure for selected SELinux man page" -msgstr "" +msgstr "選択された SELinux マニュアルページ向けの HTML マニュアルページの構成を生成する" #: ../sepolicy/sepolicy.py:213 msgid "All domains" @@ -2230,7 +2230,7 @@ msgstr "SELinux に問い合わせて boolean の詳細を表示する" #: ../sepolicy/sepolicy.py:280 msgid "get all booleans descriptions" -msgstr "" +msgstr "すべてのブーリアンの説明を取得する" #: ../sepolicy/sepolicy.py:282 msgid "boolean to get description" @@ -2252,11 +2252,11 @@ msgstr "ターゲットプロセスドメイン" #: ../sepolicy/sepolicy.py:327 msgid "Command required for this type of policy" -msgstr "" +msgstr "この種類のポリシーに対して要求されるコマンド" #: ../sepolicy/sepolicy.py:347 msgid "List SELinux Policy interfaces" -msgstr "" +msgstr "SELinux ポリシー・インターフェースの一覧表示" #: ../sepolicy/sepolicy.py:362 msgid "Generate SELinux Policy module template" @@ -2294,7 +2294,7 @@ msgstr "制限を課す実行ファイル" #: ../sepolicy/sepolicy.py:414 ../sepolicy/sepolicy.py:417 #, python-format msgid "Generate Policy for %s" -msgstr "" +msgstr "%s 向けのポリシーの生成" #: ../sepolicy/sepolicy.py:422 msgid "commands" @@ -2306,12 +2306,12 @@ msgstr "" #: ../sepolicy/sepolicy/__init__.py:48 msgid "No SELinux Policy installed" -msgstr "" +msgstr "インストールされている SELinux ポリシーがありません" #: ../sepolicy/sepolicy/__init__.py:54 #, python-format msgid "Failed to read %s policy file" -msgstr "" +msgstr "%s ポリシーファイルの読み込みに失敗しました" #: ../sepolicy/sepolicy/__init__.py:127 msgid "unknown" @@ -2335,15 +2335,15 @@ msgstr "" #: ../sepolicy/sepolicy/generate.py:180 msgid "Desktop Login User Role" -msgstr "" +msgstr "デスクトップログインユーザーロール" #: ../sepolicy/sepolicy/generate.py:181 msgid "Administrator Login User Role" -msgstr "" +msgstr "管理者のログインユーザーロール" #: ../sepolicy/sepolicy/generate.py:182 msgid "Confined Root Administrator Role" -msgstr "" +msgstr "制限された root 管理者ロール" #: ../sepolicy/sepolicy/generate.py:187 msgid "Valid Types:\n" @@ -2356,7 +2356,7 @@ msgstr "ポートは数字、又は 1 から %d までの数字の範囲でな #: ../sepolicy/sepolicy/generate.py:231 msgid "You must enter a valid policy type" -msgstr "" +msgstr "有効なポリシー種別を入力する必要があります" #: ../sepolicy/sepolicy/generate.py:234 #, python-format @@ -2460,11 +2460,11 @@ msgstr "ユーザーが RADIUS サーバーを使用してログインするこ #: booleans.py:8 msgid "Allow users to login using a yubikey server" -msgstr "" +msgstr "ユーザーが yubikey サーバーを使用してログインすることを許可する" #: booleans.py:9 msgid "Allow awstats to purge Apache logs" -msgstr "" +msgstr "awstats が Apache のログを消去することを許可する" #: booleans.py:10 msgid "" @@ -2532,11 +2532,11 @@ msgstr "すべてのデーモンが端末を読み書きすることを許可し #: booleans.py:25 msgid "Allow dan to manage user files" -msgstr "" +msgstr "dan がユーザーファイルを管理することを許可する" #: booleans.py:26 msgid "Allow dan to read user files" -msgstr "" +msgstr "dan がユーザーファイルを読み取ることを許可する" #: booleans.py:27 msgid "Allow dbadm to manage files in users home directories" @@ -2603,7 +2603,7 @@ msgstr "隔離ドメインによる ssh の実行を許可します。" #: booleans.py:42 msgid "Allow all domains to execute in fips_mode" -msgstr "" +msgstr "すべてのドメインが fips_mode で実行することを許可する" #: booleans.py:43 msgid "Allow ftp to read and write files in the user home directories" @@ -2872,7 +2872,7 @@ msgstr "あらゆるポートへの接続および予約されていないポー #: booleans.py:103 msgid "Allow confined applications to run with kerberos." -msgstr "" +msgstr "制限されたアプリケーションが Kerberos とともに動作することを許可する" #: booleans.py:104 msgid "Allow syslogd daemon to send mail" @@ -2880,11 +2880,11 @@ msgstr "syslogd デーモンがメールを送信することを許可します #: booleans.py:105 msgid "Allow syslogd the ability to read/write terminals" -msgstr "" +msgstr "syslogd が端末を読み書きすることを許可する" #: booleans.py:106 msgid "Allow logging in and using the system from /dev/console." -msgstr "" +msgstr "/dev/console からログインしてシステムを使用することを許可する" #: booleans.py:107 msgid "" @@ -2947,7 +2947,7 @@ msgstr "" #: booleans.py:120 msgid "Allow system to run with NIS" -msgstr "" +msgstr "システムが NIS を使用することを許可する" #: booleans.py:121 msgid "Allow confined applications to use nscd shared memory." @@ -3361,7 +3361,7 @@ msgstr "" #: booleans.py:211 msgid "Allow varnishd to connect to all ports, not just HTTP." -msgstr "" +msgstr "varnishd が HTTP 以外のすべてのポートに接続することを許可する" #: booleans.py:212 msgid "Ignore vbetool mmap_zero errors." @@ -3370,20 +3370,20 @@ msgstr "vbetool mmap_zero エラーを無視します。" #: booleans.py:213 msgid "" "Allow confined virtual guests to use serial/parallel communication ports" -msgstr "" +msgstr "制限された仮想マシンがシリアル/パラレル通信ポートを使用することを許可する" #: booleans.py:214 msgid "" "Allow confined virtual guests to use executable memory and executable stack" -msgstr "" +msgstr "制限された仮想マシンが実行可能なメモリおよび実行可能なスタックを使用することを許可する" #: booleans.py:215 msgid "Allow confined virtual guests to read fuse files" -msgstr "" +msgstr "制限された仮想マシンが FUSE ファイルを読み込むことを許可する" #: booleans.py:216 msgid "Allow confined virtual guests to manage nfs files" -msgstr "" +msgstr "制限された仮想マシンが NFS ファイルを管理することを許可する" #: booleans.py:217 msgid "Allow confined virtual guests to interact with rawip sockets" @@ -3391,15 +3391,15 @@ msgstr "" #: booleans.py:218 msgid "Allow confined virtual guests to manage cifs files" -msgstr "" +msgstr "制限された仮想マシンが CIFS ファイルを管理することを許可する" #: booleans.py:219 msgid "Allow confined virtual guests to interact with the sanlock" -msgstr "" +msgstr "制限された仮想マシンが sanlock と通信することを許可する" #: booleans.py:220 msgid "Allow confined virtual guests to manage device configuration, (pci)" -msgstr "" +msgstr "制限された仮想マシンがデバイス設定 (pci) を管理することを許可する" #: booleans.py:221 msgid "Allow confined virtual guests to use usb devices" @@ -3438,11 +3438,11 @@ msgstr "Xen が NFS ファイルを管理することを許可する" msgid "" "Allow xend to run blktapctrl/tapdisk. Not required if using dedicated " "logical volumes for disk images." -msgstr "" +msgstr "xend が blktapctrl/tapdisk を実行することを許可する。ディスクイメージ用の専用論理ボリュームを使用していなければ、必要ありません。" #: booleans.py:230 msgid "Allow xend to run qemu-dm. Not required if using paravirt and no vfb." -msgstr "" +msgstr "xend が qemu-dm を実行することを許可する。準仮想化を使用していて、vfb がなければ、必要ありません。" #: booleans.py:231 msgid "" @@ -3455,11 +3455,11 @@ msgstr "" #: booleans.py:233 msgid "Allow xguest users to mount removable media" -msgstr "" +msgstr "xguest ユーザーがリムーバブルメディアをマウントすることを許可する" #: booleans.py:234 msgid "Allow xguest to use blue tooth devices" -msgstr "" +msgstr "xguest が Bluetooth デバイスを使用することを許可する" #: booleans.py:235 msgid "Allows clients to write to the X server shared memory segments." diff --git a/policycoreutils/restorecond/Makefile b/policycoreutils/restorecond/Makefile index 3074542..3b704d8 100644 --- a/policycoreutils/restorecond/Makefile +++ b/policycoreutils/restorecond/Makefile @@ -5,6 +5,7 @@ LIBDIR ?= $(PREFIX)/lib MANDIR = $(PREFIX)/share/man AUTOSTARTDIR = $(DESTDIR)/etc/xdg/autostart DBUSSERVICEDIR = $(DESTDIR)/usr/share/dbus-1/services +SYSTEMDDIR ?= $(DESTDIR)/usr/lib/systemd autostart_DATA = sealertauto.desktop INITDIR = $(DESTDIR)/etc/rc.d/init.d @@ -39,7 +40,8 @@ install: all install -m 644 restorecond.desktop $(AUTOSTARTDIR)/restorecond.desktop -mkdir -p $(DBUSSERVICEDIR) install -m 600 org.selinux.Restorecond.service $(DBUSSERVICEDIR)/org.selinux.Restorecond.service - + -mkdir -p $(SYSTEMDDIR)/system + install -m 644 restorecond.service $(SYSTEMDDIR)/system/ relabel: install /sbin/restorecon $(SBINDIR)/restorecond diff --git a/policycoreutils/restorecond/restorecond.service b/policycoreutils/restorecond/restorecond.service new file mode 100644 index 0000000..11f4ffd --- /dev/null +++ b/policycoreutils/restorecond/restorecond.service @@ -0,0 +1,12 @@ +[Unit] +Description=Restorecon maintaining path file context +After=syslog.target +ConditionPathExists=/etc/selinux/restorecond.conf + +[Service] +Type=oneshot +ExecStart=/usr/sbin/restorecond +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/policycoreutils/restorecond/user.c b/policycoreutils/restorecond/user.c index 00a646f..2c28676 100644 --- a/policycoreutils/restorecond/user.c +++ b/policycoreutils/restorecond/user.c @@ -54,6 +54,7 @@ static const char *PATH="/org/selinux/Restorecond"; static const char *INTERFACE="org.selinux.RestorecondIface"; static const char *RULE="type='signal',interface='org.selinux.RestorecondIface'"; +static int local_lock_fd = -1; static DBusHandlerResult signal_filter (DBusConnection *connection __attribute__ ((__unused__)), DBusMessage *message, void *user_data) @@ -201,17 +202,18 @@ static int local_server() { perror("asprintf"); return -1; } - int fd = open(ptr, O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, S_IRUSR | S_IWUSR); + local_lock_fd = open(ptr, O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, S_IRUSR | S_IWUSR); if (debug_mode) g_warning ("Lock file: %s", ptr); free(ptr); - if (fd < 0) { + if (local_lock_fd < 0) { if (debug_mode) perror("open"); return -1; } - if (flock(fd, LOCK_EX | LOCK_NB) < 0) { + if (flock(local_lock_fd, LOCK_EX | LOCK_NB) < 0) { + close(local_lock_fd); if (debug_mode) perror("flock"); return -1; @@ -226,6 +228,12 @@ static int local_server() { return 0; } +static void end_local_server(void) { + if (local_lock_fd >= 0) + close(local_lock_fd); + local_lock_fd = -1; +} + int server(int master_fd, const char *watch_file) { GMainLoop *loop; @@ -253,6 +261,7 @@ int server(int master_fd, const char *watch_file) { g_main_loop_run (loop); end: + end_local_server(); g_main_loop_unref (loop); return 0; } diff --git a/policycoreutils/run_init/run_init.pamd b/policycoreutils/run_init/run_init.pamd index d1b435c..1c323d2 100644 --- a/policycoreutils/run_init/run_init.pamd +++ b/policycoreutils/run_init/run_init.pamd @@ -1,4 +1,6 @@ #%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 diff --git a/policycoreutils/sandbox/sandbox b/policycoreutils/sandbox/sandbox index b629006..6631c2d 100644 --- a/policycoreutils/sandbox/sandbox +++ b/policycoreutils/sandbox/sandbox @@ -243,7 +243,7 @@ class Sandbox: copyfile(f, "/tmp", self.__tmpdir) copyfile(f, "/var/tmp", self.__tmpdir) - def __setup_sandboxrc(self, wm = "/usr/bin/matchbox-window-manager -use_titlebar no"): + def __setup_sandboxrc(self, wm = "/usr/bin/openbox"): execfile =self.__homedir + "/.sandboxrc" fd = open(execfile, "w+") if self.__options.session: @@ -333,7 +333,7 @@ sandbox [-h] [-c] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile parser.add_option("-W", "--windowmanager", dest="wm", type="string", - default="/usr/bin/matchbox-window-manager -use_titlebar no", + default="/usr/bin/openbox", help=_("alternate window manager")) parser.add_option("-l", "--level", dest="level", diff --git a/policycoreutils/sandbox/sandbox.8 b/policycoreutils/sandbox/sandbox.8 index 521afcd..a50eef2 100644 --- a/policycoreutils/sandbox/sandbox.8 +++ b/policycoreutils/sandbox/sandbox.8 @@ -70,7 +70,7 @@ Specifies the windowsize when creating an X based Sandbox. The default windowsiz \fB\-W windowmanager\fR Select alternative window manager to run within .B sandbox -X. -Default to /usr/bin/matchbox-window-manager. +Default to /usr/bin/openbox. .TP \fB\-X\fR Create an X based Sandbox for gui apps, temporary files for diff --git a/policycoreutils/sandbox/sandboxX.sh b/policycoreutils/sandbox/sandboxX.sh index 23de6f6..171bb05 100644 --- a/policycoreutils/sandbox/sandboxX.sh +++ b/policycoreutils/sandbox/sandboxX.sh @@ -6,6 +6,20 @@ export TITLE="Sandbox $context -- `grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8 [ -z $2 ] && export DPI="96" || export DPI="$2" trap "exit 0" HUP +mkdir -p ~/.config/openbox +cat > ~/.config/openbox/rc.xml << EOF + + + + no + all + yes + + + +EOF + (/usr/bin/Xephyr -title "$TITLE" -terminate -screen $SCREENSIZE -dpi $DPI -nolisten tcp -displayfd 5 5>&1 2>/dev/null) | while read D; do export DISPLAY=:$D cat > ~/seremote << __EOF diff --git a/policycoreutils/sandbox/seunshare.c b/policycoreutils/sandbox/seunshare.c index dbd5977..f10df39 100644 --- a/policycoreutils/sandbox/seunshare.c +++ b/policycoreutils/sandbox/seunshare.c @@ -962,7 +962,7 @@ int main(int argc, char **argv) { char *LANG = NULL; int rc = -1; - if (unshare(CLONE_NEWNS) < 0) { + if (unshare(CLONE_NEWNS | CLONE_NEWIPC) < 0) { perror(_("Failed to unshare")); goto childerr; } diff --git a/policycoreutils/scripts/Makefile b/policycoreutils/scripts/Makefile index 201a988..f5d6e9d 100644 --- a/policycoreutils/scripts/Makefile +++ b/policycoreutils/scripts/Makefile @@ -9,23 +9,12 @@ LOCALEDIR ?= $(PREFIX)/share/locale .PHONY: all genhomedircon all: fixfiles genhomedircon chcat -genhomedircon: - @echo "#!/bin/sh" > genhomedircon - @echo >> genhomedircon - @if [ -z "${SEMODULE_PATH}" ]; then \ - echo "${USRSBINDIR}/semodule -Bn" >> genhomedircon; \ - else \ - echo "${SEMODULE_PATH}/semodule -Bn" >> genhomedircon; \ - fi - install: all -mkdir -p $(BINDIR) install -m 755 chcat $(BINDIR) install -m 755 fixfiles $(SBINDIR) - install -m 755 genhomedircon $(USRSBINDIR) -mkdir -p $(MANDIR)/man8 install -m 644 fixfiles.8 $(MANDIR)/man8/ - install -m 644 genhomedircon.8 $(MANDIR)/man8/ install -m 644 chcat.8 $(MANDIR)/man8/ clean: diff --git a/policycoreutils/scripts/genhomedircon.8 b/policycoreutils/scripts/genhomedircon.8 deleted file mode 100644 index 8ec509c..0000000 --- a/policycoreutils/scripts/genhomedircon.8 +++ /dev/null @@ -1,24 +0,0 @@ -.TH GENHOMEDIRCON "12" "Sep 2011" "Security Enhanced Linux" "SELinux" -.SH NAME -genhomedircon \- generate SELinux file context configuration entries for user home directories -.SH SYNOPSIS -.B genhomedircon -is a script that executes -.B semodule -to rebuild the currently active SELinux policy (without reloading it) and to create the -labels for each user home directory based on directory paths returned by calls to getpwent(). - -The latter functionality depends on the "usepasswd" parameter being set to "true" (default) -in /etc/selinux/semanage.conf. - -This script is usually executed by -.B semanage -although this default behavior can be optionally modified by setting to "true" the -"disable-genhomedircon" in /etc/selinux/semanage.conf. - -.SH AUTHOR -This manual page was written by -.I Dan Walsh - -.SH "SEE ALSO" -semanage.conf(5), semodule(8), semanage(8), getpwent(3), getpwent_r(3) diff --git a/policycoreutils/semanage/default_encoding/Makefile b/policycoreutils/semanage/default_encoding/Makefile new file mode 100644 index 0000000..e15a877 --- /dev/null +++ b/policycoreutils/semanage/default_encoding/Makefile @@ -0,0 +1,8 @@ +all: + LDFLAGS="" python setup.py build + +install: all + LDFLAGS="" python setup.py install --root=$(DESTDIR)/ + +clean: + rm -rf build *~ diff --git a/policycoreutils/semanage/default_encoding/default_encoding.c b/policycoreutils/semanage/default_encoding/default_encoding.c new file mode 100644 index 0000000..023b8f4 --- /dev/null +++ b/policycoreutils/semanage/default_encoding/default_encoding.c @@ -0,0 +1,57 @@ +/* + * Authors: + * John Dennis + * + * Copyright (C) 2009 Red Hat + * see file 'COPYING' for use and warranty information + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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 + */ + +#include + +PyDoc_STRVAR(setdefaultencoding_doc, +"setdefaultencoding(encoding='utf-8')\n\ +\n\ +Set the current default string encoding used by the Unicode implementation.\n\ +Defaults to utf-8." +); + +static PyObject * +setdefaultencoding(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"utf-8", NULL}; + char *encoding; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:setdefaultencoding", kwlist, &encoding)) + return NULL; + + if (PyUnicode_SetDefaultEncoding(encoding)) + return NULL; + + Py_RETURN_NONE; +} + +static PyMethodDef methods[] = { + {"setdefaultencoding", (PyCFunction)setdefaultencoding, METH_VARARGS|METH_KEYWORDS, setdefaultencoding_doc}, + {NULL, NULL} /* sentinel */ +}; + + +PyMODINIT_FUNC +initdefault_encoding_utf8(void) +{ + PyUnicode_SetDefaultEncoding("utf-8"); + Py_InitModule3("default_encoding_utf8", methods, "Forces the default encoding to utf-8"); +} diff --git a/policycoreutils/semanage/default_encoding/policycoreutils/__init__.py b/policycoreutils/semanage/default_encoding/policycoreutils/__init__.py new file mode 100644 index 0000000..ccb6b8b --- /dev/null +++ b/policycoreutils/semanage/default_encoding/policycoreutils/__init__.py @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006,2007,2008, 2009 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# diff --git a/policycoreutils/semanage/default_encoding/setup.py b/policycoreutils/semanage/default_encoding/setup.py new file mode 100644 index 0000000..e2befdb --- /dev/null +++ b/policycoreutils/semanage/default_encoding/setup.py @@ -0,0 +1,38 @@ +# Authors: +# John Dennis +# +# Copyright (C) 2009 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +from distutils.core import setup, Extension + +default_encoding_utf8 = Extension('policycoreutils.default_encoding_utf8', ['default_encoding.c']) + +setup(name = 'policycoreutils-default-encoding', + version = '0.1', + description = 'Forces the default encoding in Python to be utf-8', + long_description = 'Forces the default encoding in Python to be utf-8', + author = 'John Dennis', + author_email = 'jdennis@redhat.com', + maintainer = 'John Dennis', + maintainer_email = 'jdennis@redhat.com', + license = 'GPLv3+', + platforms = 'posix', + url = '', + download_url = '', + ext_modules = [default_encoding_utf8], + packages=["policycoreutils"], +) diff --git a/policycoreutils/semanage/semanage b/policycoreutils/semanage/semanage index 6e33c85..49e4709 100644 --- a/policycoreutils/semanage/semanage +++ b/policycoreutils/semanage/semanage @@ -20,6 +20,7 @@ # 02111-1307 USA # # +import policycoreutils.default_encoding_utf8 import sys, getopt, re import seobject import selinux @@ -32,7 +33,7 @@ gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, localedir="/usr/share/locale", - unicode=False, + unicode=True, codeset = 'utf-8') except IOError: import __builtin__ diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py index 85bc37f..02b1acd 100644 --- a/policycoreutils/semanage/seobject.py +++ b/policycoreutils/semanage/seobject.py @@ -32,11 +32,10 @@ from IPy import IP import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") gettext.textdomain(PROGNAME) -try: - gettext.install(PROGNAME, localedir = "/usr/share/locale", unicode = 1) -except IOError: - import __builtin__ - __builtin__.__dict__['_'] = unicode + +import gettext +translation=gettext.translation(PROGNAME, localedir = "/usr/share/locale", fallback=True) +_=translation.ugettext import syslog @@ -461,7 +460,9 @@ class loginRecords(semanageRecords): if rc < 0: raise ValueError(_("Could not check if login mapping for %s is defined") % name) if exists: - raise ValueError(_("Login mapping for %s is already defined") % name) + semanage_seuser_key_free(k) + return self.__modify(name, sename, serange) + if name[0] == '%': try: grp.getgrnam(name[1:]) @@ -731,7 +732,8 @@ class seluserRecords(semanageRecords): if rc < 0: raise ValueError(_("Could not check if SELinux user %s is defined") % name) if exists: - raise ValueError(_("SELinux user %s is already defined") % name) + semanage_user_key_free(k) + return self.__modify(name, roles, selevel, serange, prefix) (rc, u) = semanage_user_create(self.sh) if rc < 0: @@ -1274,7 +1276,8 @@ class nodeRecords(semanageRecords): (rc, exists) = semanage_node_exists(self.sh, k) if exists: - raise ValueError(_("Addr %s already defined") % addr) + semanage_node_key_free(k) + return self.__modify(addr, mask, self.protocol[proto], serange, ctype) (rc, node) = semanage_node_create(self.sh) if rc < 0: @@ -1475,7 +1478,8 @@ class interfaceRecords(semanageRecords): if rc < 0: raise ValueError(_("Could not check if interface %s is defined") % interface) if exists: - raise ValueError(_("Interface %s already defined") % interface) + semanage_iface_key_free(k) + return self.__modify(interface, serange, ctype) (rc, iface) = semanage_iface_create(self.sh) if rc < 0: @@ -1777,7 +1781,8 @@ class fcontextRecords(semanageRecords): raise ValueError(_("Could not check if file context for %s is defined") % target) if exists: - raise ValueError(_("File context for %s already defined") % target) + semanage_fcontext_key_free(k) + return self.__modify(target, type, ftype, serange, seuser) (rc, fcontext) = semanage_fcontext_create(self.sh) if rc < 0: diff --git a/policycoreutils/semodule/Makefile b/policycoreutils/semodule/Makefile index 4c5243a..036c418 100644 --- a/policycoreutils/semodule/Makefile +++ b/policycoreutils/semodule/Makefile @@ -11,7 +11,7 @@ LDLIBS = -lsepol -lselinux -lsemanage -L$(LIBDIR) SEMODULE_OBJS = semodule.o .PHONY: all semodule_path -all: semodule semodule_path +all: semodule semodule_path genhomedircon semodule_path: @echo -n $(SBINDIR) > ../scripts/semodule_path @@ -19,11 +19,16 @@ semodule_path: semodule: $(SEMODULE_OBJS) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) +genhomedircon: + ln -sf semodule genhomedircon + install: all -mkdir -p $(SBINDIR) install -m 755 semodule $(SBINDIR) + (cd $(SBINDIR); ln -sf semodule genhomedircon) test -d $(MANDIR)/man8 || install -m 755 -d $(MANDIR)/man8 install -m 644 semodule.8 $(MANDIR)/man8/ + install -m 644 genhomedircon.8 $(MANDIR)/man8/ relabel: diff --git a/policycoreutils/semodule/genhomedircon.8 b/policycoreutils/semodule/genhomedircon.8 new file mode 100644 index 0000000..8ec509c --- /dev/null +++ b/policycoreutils/semodule/genhomedircon.8 @@ -0,0 +1,24 @@ +.TH GENHOMEDIRCON "12" "Sep 2011" "Security Enhanced Linux" "SELinux" +.SH NAME +genhomedircon \- generate SELinux file context configuration entries for user home directories +.SH SYNOPSIS +.B genhomedircon +is a script that executes +.B semodule +to rebuild the currently active SELinux policy (without reloading it) and to create the +labels for each user home directory based on directory paths returned by calls to getpwent(). + +The latter functionality depends on the "usepasswd" parameter being set to "true" (default) +in /etc/selinux/semanage.conf. + +This script is usually executed by +.B semanage +although this default behavior can be optionally modified by setting to "true" the +"disable-genhomedircon" in /etc/selinux/semanage.conf. + +.SH AUTHOR +This manual page was written by +.I Dan Walsh + +.SH "SEE ALSO" +semanage.conf(5), semodule(8), semanage(8), getpwent(3), getpwent_r(3) diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c index 17b4fa5..6947b37 100644 --- a/policycoreutils/semodule/semodule.c +++ b/policycoreutils/semodule/semodule.c @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -284,8 +285,12 @@ int main(int argc, char *argv[]) int i, commit = 0; int result; int status = EXIT_FAILURE; - + char *genhomedirconargv[] = { "genhomedircon", "-B", "-n" }; create_signal_handlers(); + if (strcmp(basename(argv[0]), "genhomedircon") == 0) { + argc = 3; + argv=genhomedirconargv; + } parse_command_line(argc, argv); if (build) diff --git a/policycoreutils/sepolicy/Makefile b/policycoreutils/sepolicy/Makefile index 11b534f..eb86eae 100644 --- a/policycoreutils/sepolicy/Makefile +++ b/policycoreutils/sepolicy/Makefile @@ -22,10 +22,14 @@ clean: $(PYTHON) setup.py clean -rm -rf build *~ \#* *pyc .#* +sepolgen: + ln -sf sepolicy sepolgen + install: $(PYTHON) setup.py install `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` [ -d $(BINDIR) ] || mkdir -p $(BINDIR) install -m 755 sepolicy.py $(BINDIR)/sepolicy + (cd $(BINDIR); ln -sf sepolicy sepolgen) -mkdir -p $(MANDIR)/man8 install -m 644 *.8 $(MANDIR)/man8 -mkdir -p $(BASHCOMPLETIONDIR) diff --git a/policycoreutils/sepolicy/sepolgen.8 b/policycoreutils/sepolicy/sepolgen.8 new file mode 100644 index 0000000..3ecf3eb --- /dev/null +++ b/policycoreutils/sepolicy/sepolgen.8 @@ -0,0 +1 @@ +.so man8/sepolicy-generate.8 diff --git a/policycoreutils/sepolicy/sepolicy-bash-completion.sh b/policycoreutils/sepolicy/sepolicy-bash-completion.sh index 82fea52..29f9428 100644 --- a/policycoreutils/sepolicy/sepolicy-bash-completion.sh +++ b/policycoreutils/sepolicy/sepolicy-bash-completion.sh @@ -81,7 +81,7 @@ _sepolicy () { [communicate]='-h --help -s --source -t --target -c --class -S --sourceaccess -T --targetaccess' [generate]='-a --admin --admin_user --application --cgi --confined_admin --customize -d --domain --dbus --desktop_user -h --help --inetd --init -n --name --newtype -p --path --sandbox -T --test --term_user -u --user -w --writepath --x_user' [interface]='-h --help -a --list_admin" -u --list_user -l --list' - [manpage]='-h --help -p --path -a -all -o --os -d --domain -w --web' + [manpage]='-h --help -p --path -a -all -o --os -d --domain -w --web -r --root' [network]='-h --help -d --domain -l --list -p --port -t --type ' [transition]='-h --help -s --source -t --target' ) @@ -156,6 +156,10 @@ _sepolicy () { if [ "$prev" = "-d" -o "$prev" = "--domain" ]; then COMPREPLY=( $(compgen -W "$( __get_all_domains ) " -- "$cur") ) return 0 + elif test "$prev" = "-r" || test "$prev" = "--root" ; then + COMPREPLY=( $( compgen -d -- "$cur") ) + compopt -o filenames + return 0 elif [ "$prev" = "-o" -o "$prev" = "--os" ]; then return 0 elif test "$prev" = "-p" || test "$prev" = "--path" ; then diff --git a/policycoreutils/sepolicy/sepolicy-manpage.8 b/policycoreutils/sepolicy/sepolicy-manpage.8 index b6abdf5..c05c943 100644 --- a/policycoreutils/sepolicy/sepolicy-manpage.8 +++ b/policycoreutils/sepolicy/sepolicy-manpage.8 @@ -5,7 +5,7 @@ sepolicy-manpage \- Generate a man page based on the installed SELinux Policy .SH "SYNOPSIS" .br -.B sepolicy manpage [\-w] [\-h] [\-p PATH ] [\-a | \-d ] +.B sepolicy manpage [\-w] [\-h] [\-p PATH ] [\-r ROOTDIR ] [\-a | \-d ] .SH "DESCRIPTION" Use sepolicy manpage to generate manpages based on SELinux Policy. @@ -24,6 +24,9 @@ Display help message .I \-p, \-\-path Specify the directory to store the created man pages. (Default to /tmp) .TP +.I \-r, \-\-root +Specify alternate root directory to generate man pages from. (Default to /) +.TP .I \-w, \-\-web Generate an additional HTML man pages for the specified domain(s). diff --git a/policycoreutils/sepolicy/sepolicy.py b/policycoreutils/sepolicy/sepolicy.py index b25d3b2..7a15d88 100755 --- a/policycoreutils/sepolicy/sepolicy.py +++ b/policycoreutils/sepolicy/sepolicy.py @@ -22,6 +22,8 @@ # # import os, sys +import selinux +import sepolicy from sepolicy import get_os_version import argparse import gettext @@ -198,44 +200,44 @@ def network(args): _print_net(d, net, "name_bind") def manpage(args): - from sepolicy.manpage import ManPage, HTMLManPages, manpage_domains, manpage_roles, gen_domains + from sepolicy.manpage import ManPage, HTMLManPages, manpage_domains, manpage_roles, gen_domains, get_all_domains path = args.path - if args.policy: - for f in ( "policy.xml", "file_context", "file_context.homedirs"): - if not os.path.exists(path + f): - raise ValueError("manpage creation with alternate policy requires the %s file exist" % (path + f)) - + if not args.policy and args.root != "/": + sepolicy.policy(sepolicy.get_installed_policy(args.root)) + if args.all: test_domains = gen_domains() else: test_domains = args.domain for domain in test_domains: - m = ManPage(domain, path, args.web) + m = ManPage(domain, path, args.root, args.web) print m.get_man_page_path() if args.web: HTMLManPages(manpage_roles, manpage_domains, path, args.os) def gen_manpage_args(parser): - man = parser.add_parser("manpage", - help=_('Generate SELinux man pages')) - - man.add_argument("-p", "--path", dest="path", default="/tmp", - help=_("path in which the generated SELinux man pages will be stored")) - man.add_argument("-o", "--os", dest="os", default=get_os_version(), - help=_("name of the OS for man pages")) - man.add_argument("-w", "--web", dest="web", default=False, action="store_true", - help=_("Generate HTML man pages structure for selected SELinux man page")) - group = man.add_mutually_exclusive_group(required=True) - group.add_argument("-a", "--all", dest="all", default=False, - action="store_true", - help=_("All domains")) - group.add_argument("-d", "--domain", nargs="+", - action=CheckDomain, - help=_("Domain name(s) of man pages to be created")) - man.set_defaults(func=manpage) + man = parser.add_parser("manpage", + help=_('Generate SELinux man pages')) + + man.add_argument("-p", "--path", dest="path", default="/tmp", + help=_("path in which the generated SELinux man pages will be stored")) + man.add_argument("-o", "--os", dest="os", default=get_os_version(), + help=_("name of the OS for man pages")) + man.add_argument("-w", "--web", dest="web", default=False, action="store_true", + help=_("Generate HTML man pages structure for selected SELinux man page")) + man.add_argument("-r", "--root", dest="root", default="/", + help=_("Alternate root directory, defaults to /")) + group = man.add_mutually_exclusive_group(required=True) + group.add_argument("-a", "--all", dest="all", default=False, + action="store_true", + help=_("All domains")) + group.add_argument("-d", "--domain", nargs="+", + action=CheckDomain, + help=_("Domain name(s) of man pages to be created")) + man.set_defaults(func=manpage) def gen_network_args(parser): net = parser.add_parser("network", @@ -283,7 +285,6 @@ def gen_communicate_args(parser): comm.set_defaults(func=communicate) def booleans(args): - import selinux from sepolicy import boolean_desc if args.all: rc, args.booleans = selinux.security_get_boolean_names() @@ -461,7 +462,10 @@ if __name__ == '__main__': gen_transition_args(subparsers) try: - args = parser.parse_args() + if os.path.basename(sys.argv[0]) == "sepolgen": + args = parser.parse_args([ "generate" ] + sys.argv[1:]) + else: + args = parser.parse_args() args.func(args) sys.exit(0) except ValueError,e: diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py index 5e7415c..b9cb9cc 100644 --- a/policycoreutils/sepolicy/sepolicy/__init__.py +++ b/policycoreutils/sepolicy/sepolicy/__init__.py @@ -37,9 +37,30 @@ CLASS = 'class' TRANSITION = 'transition' ROLE_ALLOW = 'role_allow' -def __get_installed_policy(): +def info(setype, name=None): + dict_list = _policy.info(setype, name) + return dict_list + +def search(types, info = {} ): + valid_types = [ALLOW, AUDITALLOW, NEVERALLOW, DONTAUDIT, TRANSITION, ROLE_ALLOW] + for type in types: + if type not in valid_types: + raise ValueError("Type has to be in %s" % valid_types) + info[type] = True + + perms = [] + if PERMS in info: + perms = info[PERMS] + info[PERMS] = ",".join(info[PERMS]) + + dict_list = _policy.search(info) + if dict_list and len(perms) != 0: + dict_list = filter(lambda x: _dict_has_perms(x, perms), dict_list) + return dict_list + +def get_installed_policy(root = "/"): try: - path = selinux.selinux_binary_policy_path() + path = root + selinux.selinux_binary_policy_path() policies = glob.glob ("%s.*" % path ) policies.sort() return policies[-1] @@ -71,6 +92,7 @@ def get_all_role_allows(): return role_allows def get_all_entrypoint_domains(): + import re all_domains = [] types=get_all_types() types.sort() @@ -85,7 +107,7 @@ all_domains = None def get_all_domains(): global all_domains if not all_domains: - all_domains = info(ATTRIBUTE,"domain")[0]["types"] + all_domains = info(ATTRIBUTE,"domain")[0]["types"] return all_domains roles = None @@ -139,49 +161,43 @@ def get_all_attributes(): return all_attributes def policy(policy_file): + global all_domains + global all_attributes + global bools + global all_types + global role_allows + global users + global roles + global file_types + global port_types + all_domains = None + all_attributes = None + bools = None + all_types = None + role_allows = None + users = None + roles = None + file_types = None + port_types = None try: _policy.policy(policy_file) except: raise ValueError(_("Failed to read %s policy file") % policy_file) -policy_file = selinux.selinux_current_policy_path() -if not policy_file: - policy_file = __get_installed_policy() - try: + policy_file = get_installed_policy() policy(policy_file) except ValueError, e: if selinux.is_selinux_enabled() == 1: raise e -def search(types, info = {} ): - valid_types = [ALLOW, AUDITALLOW, NEVERALLOW, DONTAUDIT, TRANSITION, ROLE_ALLOW] - for type in types: - if type not in valid_types: - raise ValueError("Type has to be in %s" % valid_types) - info[type] = True - - perms = [] - if PERMS in info: - perms = info[PERMS] - info[PERMS] = ",".join(info[PERMS]) - - dict_list = _policy.search(info) - if dict_list and len(perms) != 0: - dict_list = filter(lambda x: _dict_has_perms(x, perms), dict_list) - return dict_list - def _dict_has_perms(dict, perms): for perm in perms: if perm not in dict[PERMS]: return False return True -def info(setype, name=None): - dict_list = _policy.info(setype, name) - return dict_list - booleans_dict = None def gen_bool_dict(path="/usr/share/selinux/devel/policy.xml"): global booleans_dict diff --git a/policycoreutils/sepolicy/sepolicy/generate.py b/policycoreutils/sepolicy/sepolicy/generate.py index 26f8390..19f6056 100644 --- a/policycoreutils/sepolicy/sepolicy/generate.py +++ b/policycoreutils/sepolicy/sepolicy/generate.py @@ -1037,7 +1037,8 @@ allow %s_t %s_t:%s_socket name_%s; ######################################## # # %s local policy -#""" % self.name +# +""" % self.name newte += self.generate_capabilities() newte += self.generate_process() newte += self.generate_network_types() diff --git a/policycoreutils/sepolicy/sepolicy/manpage.py b/policycoreutils/sepolicy/sepolicy/manpage.py index 25062da..da17c48 100755 --- a/policycoreutils/sepolicy/sepolicy/manpage.py +++ b/policycoreutils/sepolicy/sepolicy/manpage.py @@ -24,11 +24,12 @@ # __all__ = [ 'ManPage', 'HTMLManPages', 'manpage_domains', 'manpage_roles', 'gen_domains' ] +from sepolicy import network import string import argparse import selinux import sepolicy -from sepolicy import network, gen_bool_dict, get_all_file_types, get_all_domains, get_all_roles, get_all_users, get_all_port_types, get_all_bools, get_all_attributes, get_all_role_allows +from sepolicy import * import commands import sys, os, re, time @@ -416,40 +417,33 @@ class ManPage: """ Generate a Manpage on an SELinux domain in the specified path """ - all_attributes = get_all_attributes() - all_domains = get_all_domains() - all_bools = get_all_bools() - all_port_types = get_all_port_types() - all_roles = get_all_roles() - all_users = get_all_users_info()[0] - all_users_range = get_all_users_info()[1] - all_file_types = get_all_file_types() - types = _gen_types() modules_dict = None - domains = gen_domains() - role_allows = get_all_role_allows() enabled_str = ["Disabled", "Enabled"] - def __init__(self, domainname, path = "/tmp", html = False): + def __init__(self, domainname, path = "/tmp", root="/", html = False): self.html = html + self.root = root self.portrecs = network.portrecs - - fcpath = path + "/file_contexts" - if os.path.exists(fcpath): - self.fcpath = fcpath - else: - self.fcpath = selinux.selinux_file_context_path() + self.domains = gen_domains() + self.all_domains = get_all_domains() + self.all_attributes = get_all_attributes() + self.all_bools = get_all_bools() + self.all_port_types = get_all_port_types() + self.all_roles = get_all_roles() + self.all_users = get_all_users_info()[0] + self.all_users_range = get_all_users_info()[1] + self.all_file_types = get_all_file_types() + self.role_allows = get_all_role_allows() + self.types = _gen_types() + + self.fcpath = self.root + selinux.selinux_file_context_path() self.fcdict = _gen_fcdict(self.fcpath) if not os.path.exists(path): os.makedirs(path) - self.path = path - xmlpath = path + "/policy.xml" - if os.path.exists(xmlpath): - self.xmlpath = xmlpath - else: - self.xmlpath = "/usr/share/selinux/devel/policy.xml" + self.path = path + self.xmlpath = self.root + "/usr/share/selinux/devel/policy.xml" self.booleans_dict = gen_bool_dict(self.xmlpath) if domainname.endswith("_t"): @@ -947,13 +941,14 @@ semanage fcontext -a -t public_content_t "/var/%(domainname)s(/.*)?" .B restorecon -F -R -v /var/%(domainname)s .pp .TP -Allow %(domainname)s servers to read and write /var/tmp/incoming by adding the public_content_rw_t type to the directory and by restoring the file type. This also requires the allow_%(domainname)sd_anon_write boolean to be set. +Allow %(domainname)s servers to read and write /var/%(domainname)s/incoming by adding the public_content_rw_t type to the directory and by restoring the file type. You also need to turn on the %(domainname)s_anon_write boolean. .PP .B semanage fcontext -a -t public_content_rw_t "/var/%(domainname)s/incoming(/.*)?" .br .B restorecon -F -R -v /var/%(domainname)s/incoming - +.br +.B setsebool -P %(domainname)s_anon_write 1 """ % {'domainname':self.domainname}) for b in self.anon_list: desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:] @@ -1230,6 +1225,7 @@ The SELinux user %s_u is not able to terminal login. """ % self.domainname) def _network(self): + from sepolicy import network self.fd.write(""" .SH NETWORK """) diff --git a/policycoreutils/setfiles/restorecon.8 b/policycoreutils/setfiles/restorecon.8 index 80b6d6e..07c5ee2 100644 --- a/policycoreutils/setfiles/restorecon.8 +++ b/policycoreutils/setfiles/restorecon.8 @@ -4,10 +4,10 @@ restorecon \- restore file(s) default SELinux security contexts. .SH "SYNOPSIS" .B restorecon -.I [\-o outfilename] [\-R] [\-n] [\-p] [\-v] [\-e directory] pathname... +.I [\-R] [\-n] [\-p] [\-v] [\-e directory] pathname... .P .B restorecon -.I \-f infilename [\-o outfilename] [\-e directory] [\-R] [\-n] [\-p] [\-v] [\-F] +.I \-f infilename [\-e directory] [\-R] [\-n] [\-p] [\-v] [\-F] .SH "DESCRIPTION" This manual page describes the @@ -49,7 +49,7 @@ ignore files that do not exist. don't change any file labels (passive check). .TP .B \-o outfilename -save list of files with incorrect context in outfilename. +Deprecated, SELinux policy will probably block this access. Use shell redirection to save list of files with incorrect context in filename. .TP .B \-p show progress by printing * every STAR_COUNT files. (If you relabel the entire OS, this will show you the percentage complete.) diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8 index 89d2a49..12bca43 100644 --- a/policycoreutils/setfiles/setfiles.8 +++ b/policycoreutils/setfiles/setfiles.8 @@ -4,7 +4,7 @@ setfiles \- set SELinux file security contexts. .SH "SYNOPSIS" .B setfiles -.I [\-c policy] [\-d] [\-l] [\-n] [\-e directory] [\-o filename] [\-q] [\-s] [\-v] [\-W] [\-F] spec_file pathname... +.I [\-c policy] [\-d] [\-l] [\-n] [\-e directory] [\-q] [\-s] [\-v] [\-W] [\-F] spec_file pathname... .SH "DESCRIPTION" This manual page describes the .BR setfiles @@ -57,7 +57,7 @@ log changes in file labels to syslog. don't change any file labels (passive check). .TP .B \-o filename -save list of files with incorrect context in filename. +Deprecated, SELinux policy will probably block this access. Use shell redirection to save list of files with incorrect context in filename. .TP .B \-p show progress by printing * every STAR_COUNT files. (If you relabel the entire OS, this will show you the percentage complete.) diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c index b11e49f..d3f02ae 100644 --- a/policycoreutils/setfiles/setfiles.c +++ b/policycoreutils/setfiles/setfiles.c @@ -45,14 +45,14 @@ void usage(const char *const name) { if (iamrestorecon) { fprintf(stderr, - "usage: %s [-iFnprRv0] [-e excludedir] [-o filename] pathname...\n" - "usage: %s [-iFnprRv0] [-e excludedir] [-o filename] -f filename\n", + "usage: %s [-iFnprRv0] [-e excludedir] pathname...\n" + "usage: %s [-iFnprRv0] [-e excludedir] -f filename\n", name, name); } else { fprintf(stderr, - "usage: %s [-dilnpqvFW] [-e excludedir] [-o filename] [-r alt_root_path] spec_file pathname...\n" - "usage: %s [-dilnpqvFW] [-e excludedir] [-o filename] [-r alt_root_path] spec_file -f filename\n" - "usage: %s -s [-dilnpqvFW] [-o filename] spec_file\n" + "usage: %s [-dilnpqvFW] [-e excludedir] [-r alt_root_path] spec_file pathname...\n" + "usage: %s [-dilnpqvFW] [-e excludedir] [-r alt_root_path] spec_file -f filename\n" + "usage: %s -s [-dilnpqvFW] spec_file\n" "usage: %s -c policyfile spec_file\n", name, name, name, name); }