mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-04 00:05:14 +00:00
Compare commits
124 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f97782b100 | ||
|
aa7dc70de3 | ||
|
3f1ed05da6 | ||
|
971908b730 | ||
|
481f59a39b | ||
|
9e48a5da5e | ||
|
4814763c97 | ||
|
1328a42d5a | ||
|
be94d7b27f | ||
|
2ad924f2b1 | ||
|
bf662b5594 | ||
|
110b96bd3d | ||
|
10a4b3b9fb | ||
|
419d82c13b | ||
|
26b6dc1306 | ||
|
63b7cb0660 | ||
|
30e0eacebc | ||
|
1f36505f3e | ||
|
8d9c904174 | ||
|
4c7924ec31 | ||
|
b4a5f44473 | ||
|
e9d9395f91 | ||
|
b950c76d66 | ||
|
95912e41bf | ||
|
64c196a487 | ||
|
df0a2335f2 | ||
|
f472b6bb34 | ||
|
059adcdf76 | ||
|
a7ffae4396 | ||
|
5d973c2657 | ||
|
c4e607199c | ||
|
e28d0a922a | ||
|
b74f224106 | ||
|
0b18e57cc5 | ||
|
b714cf1b0d | ||
|
b7732a2a30 | ||
|
6b78daf25b | ||
|
26a8b72225 | ||
|
36bdd6ea70 | ||
|
0d0a196077 | ||
|
5e187daa0b | ||
|
776975dc38 | ||
|
f3c39034ae | ||
|
45922c6d21 | ||
|
80d900d18c | ||
|
812d53b546 | ||
|
4ffcb2a8a9 | ||
|
96b339f870 | ||
|
b4fa0cf9f6 | ||
|
f0876ea92a | ||
|
06069cc47a | ||
|
0c2690d819 | ||
|
47da50b7e6 | ||
|
50ee50f931 | ||
|
566f656101 | ||
|
11ae3f6ecd | ||
|
671ddccf19 | ||
|
4395d6dea8 | ||
|
86ec3dd658 | ||
|
14096cb3a7 | ||
|
208933829f | ||
|
cea8e7cfa0 | ||
|
c9bf36dd2e | ||
|
e6ef536957 | ||
|
dc7c702188 | ||
|
3b5683be29 | ||
|
f9eb3fea0f | ||
|
130958a4a4 | ||
|
2bc64070c9 | ||
|
1f9085e5e7 | ||
|
46f88f5f0d | ||
|
f8c535801e | ||
|
8b3997aa0e | ||
|
7f643fbc31 | ||
|
275c7c0d50 | ||
|
d66720ef07 | ||
|
22e94633c3 | ||
|
ccef9161a8 | ||
|
b21b28f486 | ||
|
735afbc947 | ||
|
1c3839c39a | ||
|
86db2263b8 | ||
|
41b6182019 | ||
|
8ef7b59454 | ||
|
0eefeeb0e7 | ||
|
21b0d14ea4 | ||
|
11e7dab95e | ||
|
e88af93322 | ||
|
ad5e988efb | ||
|
b0456adbd8 | ||
|
8dd517f6dd | ||
|
547708bc99 | ||
|
8f6d94bf44 | ||
|
0b93a7f991 | ||
|
e2c1b21dec | ||
|
cb4f553d60 | ||
|
967d394ef4 | ||
|
705ce5ca3e | ||
|
6d22c871bf | ||
|
a3db7f8acb | ||
|
7f1007d13e | ||
|
f8a174c08b | ||
|
cab3210bd0 | ||
|
85f8cace12 | ||
|
26af640fda | ||
|
1bac9d2d79 | ||
|
e1929298ac | ||
|
8fc3dcb312 | ||
|
6f1d054468 | ||
|
ef718df685 | ||
|
2ea3309942 | ||
|
8d142809f5 | ||
|
efd8eedd52 | ||
|
62dbd29656 | ||
|
1b51dac4c9 | ||
|
1361116542 | ||
|
8b17fd1fa6 | ||
|
6ab19ea82f | ||
|
1541175c36 | ||
|
cb5cdf2656 | ||
|
1b58f226ce | ||
|
d71e46baaa | ||
|
924983e702 | ||
|
6344b8ecc3 |
2
Makefile
2
Makefile
@@ -56,6 +56,8 @@ coverity: snapshot
|
|||||||
cd $(SNAPSHOT_NAME)/libraries/libapparmor && ./configure --with-python
|
cd $(SNAPSHOT_NAME)/libraries/libapparmor && ./configure --with-python
|
||||||
$(foreach dir, $(filter-out utils profiles tests, $(DIRS)), \
|
$(foreach dir, $(filter-out utils profiles tests, $(DIRS)), \
|
||||||
cov-build --dir $(COVERITY_DIR) -- $(MAKE) -C $(SNAPSHOT_NAME)/$(dir);)
|
cov-build --dir $(COVERITY_DIR) -- $(MAKE) -C $(SNAPSHOT_NAME)/$(dir);)
|
||||||
|
$(foreach dir, libraries/libapparmor utils, \
|
||||||
|
cov-build --dir $(COVERITY_DIR) --no-command --fs-capture-search $(SNAPSHOT_NAME)/$(dir);)
|
||||||
tar -cvzf $(SNAPSHOT_NAME)-$(COVERITY_DIR).tar.gz $(COVERITY_DIR)
|
tar -cvzf $(SNAPSHOT_NAME)-$(COVERITY_DIR).tar.gz $(COVERITY_DIR)
|
||||||
|
|
||||||
.PHONY: export_dir
|
.PHONY: export_dir
|
||||||
|
@@ -1,3 +1,9 @@
|
|||||||
|
# AppArmor
|
||||||
|
|
||||||
|
[](https://gitlab.com/apparmor/apparmor/commits/master)
|
||||||
|
[](https://gitlab.com/apparmor/apparmor/pipelines)
|
||||||
|
[](https://bestpractices.coreinfrastructure.org/projects/1699)
|
||||||
|
|
||||||
------------
|
------------
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
@@ -8,14 +8,14 @@ msgstr ""
|
|||||||
"Project-Id-Version: apparmor\n"
|
"Project-Id-Version: apparmor\n"
|
||||||
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
||||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||||
"PO-Revision-Date: 2017-12-21 12:20+0000\n"
|
"PO-Revision-Date: 2018-02-09 23:55+0000\n"
|
||||||
"Last-Translator: Christian Boltz <Unknown>\n"
|
"Last-Translator: Tobias Bannert <tobannert@gmail.com>\n"
|
||||||
"Language-Team: German <de@li.org>\n"
|
"Language-Team: German <de@li.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Launchpad-Export-Date: 2017-12-22 05:12+0000\n"
|
"X-Launchpad-Export-Date: 2018-02-11 05:14+0000\n"
|
||||||
"X-Generator: Launchpad (build 18521)\n"
|
"X-Generator: Launchpad (build 18544)\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
|
|
||||||
#: ../aa_enabled.c:26
|
#: ../aa_enabled.c:26
|
||||||
@@ -59,15 +59,15 @@ msgstr "Nein – beim Start deaktiviert.\n"
|
|||||||
#: ../aa_enabled.c:77
|
#: ../aa_enabled.c:77
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Maybe - policy interface not available.\n"
|
msgid "Maybe - policy interface not available.\n"
|
||||||
msgstr ""
|
msgstr "Vielleicht – Richtlinienschnittstelle nicht verfügbar.\n"
|
||||||
|
|
||||||
#: ../aa_enabled.c:81
|
#: ../aa_enabled.c:81
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Vielleicht - ungenügende Berechtigungen, um die Verfügbarkeit zu prüfen\n"
|
"Vielleicht – ungenügende Berechtigungen, um die Verfügbarkeit zu prüfen\n"
|
||||||
|
|
||||||
#: ../aa_enabled.c:84
|
#: ../aa_enabled.c:84
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error - '%s'\n"
|
msgid "Error - '%s'\n"
|
||||||
msgstr "Fehler - »%s«\n"
|
msgstr "Fehler – »%s«\n"
|
||||||
|
@@ -82,7 +82,7 @@ SECDIR ?= ${DESTDIR}/lib/security
|
|||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: $(NAME).so
|
install: $(NAME).so
|
||||||
install -m 755 -d $(SECDIR)
|
install -m 755 -d $(SECDIR)
|
||||||
install -m 555 $(NAME).so $(SECDIR)/
|
install -m 755 $(NAME).so $(SECDIR)/
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
@@ -1 +1 @@
|
|||||||
2.12
|
2.13
|
||||||
|
BIN
documentation/toxie.png
Normal file
BIN
documentation/toxie.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,13 @@
|
|||||||
From a3b0cb6676a04cdad5cc357bc422d0398083b435 Mon Sep 17 00:00:00 2001
|
From 2e7f6d0dc0f1d3642950f529b451af73fa1baf9c Mon Sep 17 00:00:00 2001
|
||||||
From: John Johansen <john.johansen@canonical.com>
|
From: John Johansen <john.johansen@canonical.com>
|
||||||
Date: Tue, 18 Jul 2017 23:27:23 -0700
|
Date: Tue, 18 Jul 2017 23:27:23 -0700
|
||||||
Subject: [PATCH 17/17] UBUNTU: SAUCE: apparmor: af_unix mediation
|
Subject: [PATCH 2/2] apparmor: af_unix mediation
|
||||||
|
|
||||||
af_socket mediation did not make it into 4.14 so add remaining out
|
af_socket mediation did not make it into 4.14 so add remaining out
|
||||||
of tree patch
|
of tree patch
|
||||||
|
|
||||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||||
|
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
|
||||||
---
|
---
|
||||||
security/apparmor/Makefile | 3 +-
|
security/apparmor/Makefile | 3 +-
|
||||||
security/apparmor/af_unix.c | 651 ++++++++++++++++++++++++++++++++++++
|
security/apparmor/af_unix.c | 651 ++++++++++++++++++++++++++++++++++++
|
||||||
@@ -23,10 +24,10 @@ Signed-off-by: John Johansen <john.johansen@canonical.com>
|
|||||||
create mode 100644 security/apparmor/include/af_unix.h
|
create mode 100644 security/apparmor/include/af_unix.h
|
||||||
|
|
||||||
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
|
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
|
||||||
index dafdd387d42b..ef39226ff4aa 100644
|
index e7ff2183532a..90c118f39e13 100644
|
||||||
--- a/security/apparmor/Makefile
|
--- a/security/apparmor/Makefile
|
||||||
+++ b/security/apparmor/Makefile
|
+++ b/security/apparmor/Makefile
|
||||||
@@ -4,7 +4,8 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
|
@@ -5,7 +5,8 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
|
||||||
|
|
||||||
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
|
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
|
||||||
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
|
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
|
||||||
@@ -694,7 +695,7 @@ index 000000000000..c6876db2dbde
|
|||||||
+ return error;
|
+ return error;
|
||||||
+}
|
+}
|
||||||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||||
index 125dad5c3fde..20cdb1c4b266 100644
|
index 518d5928661b..63a8a462fc96 100644
|
||||||
--- a/security/apparmor/apparmorfs.c
|
--- a/security/apparmor/apparmorfs.c
|
||||||
+++ b/security/apparmor/apparmorfs.c
|
+++ b/security/apparmor/apparmorfs.c
|
||||||
@@ -2187,6 +2187,11 @@ static struct aa_sfs_entry aa_sfs_entry_ns[] = {
|
@@ -2187,6 +2187,11 @@ static struct aa_sfs_entry aa_sfs_entry_ns[] = {
|
||||||
@@ -920,7 +921,7 @@ index 4364088a0b9e..26660a1a50b0 100644
|
|||||||
if (!state)
|
if (!state)
|
||||||
return 0;
|
return 0;
|
||||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||||
index cc5ab23a2d84..0ede66d80a53 100644
|
index 72b915dfcaf7..5533d2f1d9de 100644
|
||||||
--- a/security/apparmor/lsm.c
|
--- a/security/apparmor/lsm.c
|
||||||
+++ b/security/apparmor/lsm.c
|
+++ b/security/apparmor/lsm.c
|
||||||
@@ -26,6 +26,7 @@
|
@@ -26,6 +26,7 @@
|
||||||
@@ -1390,5 +1391,5 @@ index 33d54435f8d6..dd1953b08e58 100644
|
|||||||
+ aa_label_sk_perm(label, op, request, sock->sk));
|
+ aa_label_sk_perm(label, op, request, sock->sk));
|
||||||
}
|
}
|
||||||
--
|
--
|
||||||
2.11.0
|
2.14.1
|
||||||
|
|
@@ -1,4 +1,4 @@
|
|||||||
This series is based on what is currently in linux-next scheduled for
|
This is based on v4.14 final
|
||||||
inclusion in 4.14
|
|
||||||
|
|
||||||
af_unix-mediation is the last remaining patch that is out of tree
|
base socket mediation and af_unix-mediation are the last two remaining
|
||||||
|
patches that are out of tree
|
||||||
|
File diff suppressed because it is too large
Load Diff
1395
kernel-patches/v4.15/0002-apparmor-af_unix-mediation.patch
Normal file
1395
kernel-patches/v4.15/0002-apparmor-af_unix-mediation.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,8 @@ aa_features_is_equal - equality test for two aa_features objects
|
|||||||
|
|
||||||
aa_features_supports - provides aa_features object support status
|
aa_features_supports - provides aa_features object support status
|
||||||
|
|
||||||
|
aa_features_id - provides unique identifier for an aa_features object
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
B<#include E<lt>sys/apparmor.hE<gt>>
|
B<#include E<lt>sys/apparmor.hE<gt>>
|
||||||
@@ -62,6 +64,8 @@ B<bool aa_features_is_equal(aa_features *features1, aa_features *features2);>
|
|||||||
|
|
||||||
B<bool aa_features_supports(aa_features *features, const char *str);>
|
B<bool aa_features_supports(aa_features *features, const char *str);>
|
||||||
|
|
||||||
|
B<char *aa_features_id(aa_features *features);>
|
||||||
|
|
||||||
Link with B<-lapparmor> when compiling.
|
Link with B<-lapparmor> when compiling.
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
@@ -108,6 +112,12 @@ the path, relative to the "apparmor/features/" directory of securityfs, of the
|
|||||||
feature to query. For example, to test if policy version 6 is supported, I<str>
|
feature to query. For example, to test if policy version 6 is supported, I<str>
|
||||||
would be "policy/versions/v6".
|
would be "policy/versions/v6".
|
||||||
|
|
||||||
|
The aa_features_id() function returns a string representation of an
|
||||||
|
identifier that can be used to uniquely identify an I<aa_features> object.
|
||||||
|
The mechanism for generating the string representation is internal to
|
||||||
|
libapparmor and subject to change but an example implementation is
|
||||||
|
applying a hash function to the features string.
|
||||||
|
|
||||||
=head1 RETURN VALUE
|
=head1 RETURN VALUE
|
||||||
|
|
||||||
The aa_features_new() family of functions return 0 on success and I<*features>
|
The aa_features_new() family of functions return 0 on success and I<*features>
|
||||||
@@ -126,15 +136,20 @@ and false if they are not equal.
|
|||||||
aa_features_supports() returns true if the feature represented by I<str> is
|
aa_features_supports() returns true if the feature represented by I<str> is
|
||||||
supported and false if it is not supported.
|
supported and false if it is not supported.
|
||||||
|
|
||||||
|
aa_features_id() returns a string identifying I<features> which must be
|
||||||
|
freed by the caller. NULL is returned on error, with errno set
|
||||||
|
appropriately.
|
||||||
|
|
||||||
=head1 ERRORS
|
=head1 ERRORS
|
||||||
|
|
||||||
The errno value will be set according to the underlying error in the
|
The errno value will be set according to the underlying error in the
|
||||||
I<aa_features> family of functions that return -1 on error.
|
I<aa_features> family of functions that return -1 or NULL on error.
|
||||||
|
|
||||||
=head1 NOTES
|
=head1 NOTES
|
||||||
|
|
||||||
All aa_features functions described above are present in libapparmor version
|
The aa_features_id() function can be found in libapparmor version
|
||||||
2.10 and newer.
|
2.13. All the other aa_feature functions described above are present
|
||||||
|
in libapparmor version 2.10.
|
||||||
|
|
||||||
aa_features_unref() saves the value of errno when called and restores errno
|
aa_features_unref() saves the value of errno when called and restores errno
|
||||||
before exiting in libapparmor version 2.12 and newer.
|
before exiting in libapparmor version 2.12 and newer.
|
||||||
|
@@ -34,6 +34,10 @@ aa_policy_cache_remove - removes all policy cache files under a path
|
|||||||
|
|
||||||
aa_policy_cache_replace_all - performs a kernel policy replacement of all cached policies
|
aa_policy_cache_replace_all - performs a kernel policy replacement of all cached policies
|
||||||
|
|
||||||
|
aa_policy_cache_dir_path - returns the path to the aa_policy_cache directory
|
||||||
|
|
||||||
|
aa_policy_cache_dir_path_preview - returns a preview of the path to the aa_policy_cache directory without an existing aa_policy_cache object
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
B<#include E<lt>sys/apparmor.hE<gt>>
|
B<#include E<lt>sys/apparmor.hE<gt>>
|
||||||
@@ -42,6 +46,8 @@ B<typedef struct aa_policy_cache aa_policy_cache;>
|
|||||||
|
|
||||||
B<int aa_policy_cache_new(aa_policy_cache **policy_cache, aa_features *kernel_features, int dirfd, const char *path, uint16_t max_caches);>
|
B<int aa_policy_cache_new(aa_policy_cache **policy_cache, aa_features *kernel_features, int dirfd, const char *path, uint16_t max_caches);>
|
||||||
|
|
||||||
|
B<int aa_policy_cache_add_ro_dir(aa_policy_cache *policy_cache, int dirfd, const char *path);>
|
||||||
|
|
||||||
B<aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache);>
|
B<aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache);>
|
||||||
|
|
||||||
B<void aa_policy_cache_unref(aa_policy_cache *policy_cache);>
|
B<void aa_policy_cache_unref(aa_policy_cache *policy_cache);>
|
||||||
@@ -50,6 +56,10 @@ B<int aa_policy_cache_remove(int dirfd, const char *path);>
|
|||||||
|
|
||||||
B<int aa_policy_cache_replace_all(aa_policy_cache *policy_cache, aa_kernel_interface *kernel_interface);>
|
B<int aa_policy_cache_replace_all(aa_policy_cache *policy_cache, aa_kernel_interface *kernel_interface);>
|
||||||
|
|
||||||
|
B<char *aa_policy_cache_dir_path(aa_policy_cache *policy_cache, int level);>
|
||||||
|
|
||||||
|
B<char *aa_policy_cache_dir_path_preview(aa_features *kernel_features, int dirfd, const char *path);>
|
||||||
|
|
||||||
Link with B<-lapparmor> when compiling.
|
Link with B<-lapparmor> when compiling.
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
@@ -59,19 +69,35 @@ policy cache files. The policy cache files are the binary representation of a
|
|||||||
human-readable AppArmor profile. The binary representation is the form that is
|
human-readable AppArmor profile. The binary representation is the form that is
|
||||||
loaded into the kernel.
|
loaded into the kernel.
|
||||||
|
|
||||||
The aa_policy_cache_new() function creates an I<aa_policy_cache> object based
|
The aa_policy_cache_new() function creates an I<aa_policy_cache>
|
||||||
upon a directory file descriptor and path. The I<path> must point to a
|
object based upon a directory file descriptor and path. See the
|
||||||
directory. See the openat(2) man page for examples of I<dirfd> and I<path>. If
|
openat(2) man page for examples of I<dirfd> and I<path>. The I<path>
|
||||||
I<kernel_features> is NULL, then the features of the current kernel are used.
|
must point to a directory and it will be used as the basis for the
|
||||||
When specifying a valid I<kernel_features> object, it must be the compatible
|
location of policy cache files. See I<aa_policy_cache_dir_path> to
|
||||||
with the features of the kernel of interest. The value of I<max_caches> should
|
find out which directory will be used to store the binary policy cache
|
||||||
be equal to the number of caches that should be allowed before old caches are
|
files. If additional overlay cache directories are used (see
|
||||||
automatically reaped. The definition of what is considered to be an old cache
|
I<aa_policy_cache_add_ro_dir>) the directory specified in
|
||||||
is private to libapparmor. Specifying 0 means that no new caches should be
|
I<aa_policy_cache_new> is the first directory searched and is the
|
||||||
created and only existing, valid caches may be used. Specifying UINT16_MAX
|
writable overlay. If I<kernel_features> is NULL, then the features of
|
||||||
means that a new cache may be created and that the reaping of old caches is
|
the current kernel are used. When specifying a valid
|
||||||
disabled. The allocated I<aa_policy_cache> object must be freed using
|
I<kernel_features> object, it must be compatible with the features
|
||||||
aa_policy_cache_unref().
|
of the kernel of interest. The value of I<max_caches> should be equal
|
||||||
|
to the number of caches that should be allowed before old caches are
|
||||||
|
automatically reaped. The definition of what is considered to be an
|
||||||
|
old cache is private to libapparmor. Specifying 0 means that no new
|
||||||
|
caches should be created and only existing, valid caches may be used.
|
||||||
|
Specifying UINT16_MAX means that a new cache may be created and that
|
||||||
|
the reaping of old caches is disabled. The allocated
|
||||||
|
I<aa_policy_cache> object must be freed using aa_policy_cache_unref().
|
||||||
|
|
||||||
|
The aa_policy_cache_add_ro_dir() function adds an existing cache directory
|
||||||
|
to the policy cache, as a readonly layer under the primary directory
|
||||||
|
the cache was created with. When the cache is searched for an existing
|
||||||
|
cache file the primary directory will be searched and then the readonly
|
||||||
|
directories in the order that they were added to the policy cache.
|
||||||
|
This allows the policy cache to be seeded with precompiled policy
|
||||||
|
that can be updated by overlaying the read only cache file with one
|
||||||
|
written to the primary cache dir.
|
||||||
|
|
||||||
aa_policy_cache_ref() increments the reference count on the I<policy_cache>
|
aa_policy_cache_ref() increments the reference count on the I<policy_cache>
|
||||||
object.
|
object.
|
||||||
@@ -90,6 +116,18 @@ the I<policy_cache> object. If I<kernel_interface> is NULL, then the current
|
|||||||
kernel interface is used. When specifying a valid I<kernel_interface> object,
|
kernel interface is used. When specifying a valid I<kernel_interface> object,
|
||||||
it must be the interface of the currently running kernel.
|
it must be the interface of the currently running kernel.
|
||||||
|
|
||||||
|
The aa_policy_cache_dir_path() function provides the path to the cache
|
||||||
|
directory for a I<policy_cache> object at I<level> in the policy cache
|
||||||
|
overlay of cache directories. A I<level> of 0 will always be present
|
||||||
|
and is the first directory to search in an overlay of cache
|
||||||
|
directories, and will also be the writable cache directory
|
||||||
|
layer. Binary policy cache files will be located in the directory
|
||||||
|
returned by this function.
|
||||||
|
|
||||||
|
The aa_policy_cache_dir_levels() function provides access to the number
|
||||||
|
of directories that are being overlayed to create the policy cache.
|
||||||
|
|
||||||
|
|
||||||
=head1 RETURN VALUE
|
=head1 RETURN VALUE
|
||||||
|
|
||||||
The aa_policy_cache_new() function returns 0 on success and I<*policy_cache>
|
The aa_policy_cache_new() function returns 0 on success and I<*policy_cache>
|
||||||
@@ -102,15 +140,29 @@ aa_policy_cache_ref() returns the value of I<policy_cache>.
|
|||||||
aa_policy_cache_remove() and aa_policy_cache_replace_all() return 0 on success.
|
aa_policy_cache_remove() and aa_policy_cache_replace_all() return 0 on success.
|
||||||
-1 is returned on error, with errno set appropriately.
|
-1 is returned on error, with errno set appropriately.
|
||||||
|
|
||||||
|
aa_policy_cache_dir_path() returns a path string which must be freed by the
|
||||||
|
caller. NULL is returned on error, with errno set appropriately.
|
||||||
|
|
||||||
|
aa_policy_cache_dir_levels() returns a number indicating the number of
|
||||||
|
directory levels there are associated with the I<policy_cache>.
|
||||||
|
|
||||||
|
aa_policy_cache_dir_path_preview() is the same as
|
||||||
|
aa_policy_cache_dir_path() except that it doesn't require an existing
|
||||||
|
I<aa_policy_cache> object. This is useful if the calling program cannot
|
||||||
|
create an I<aa_policy_cache> object due to lack of privileges needed to
|
||||||
|
create the cache directory.
|
||||||
|
|
||||||
=head1 ERRORS
|
=head1 ERRORS
|
||||||
|
|
||||||
The errno value will be set according to the underlying error in the
|
The errno value will be set according to the underlying error in the
|
||||||
I<aa_policy_cache> family of functions that return -1 on error.
|
I<aa_policy_cache> family of functions that return -1 or NULL on error.
|
||||||
|
|
||||||
=head1 NOTES
|
=head1 NOTES
|
||||||
|
|
||||||
All aa_policy_cache functions described above are present in libapparmor
|
All aa_policy_cache functions described above, except for the
|
||||||
version 2.10 and newer.
|
aa_policy_cache_dir_path() function was added in libapparmor version
|
||||||
|
2.13. All the other aa_policy_cache functions described above are
|
||||||
|
present in libapparmor version 2.10.
|
||||||
|
|
||||||
aa_policy_cache_unref() saves the value of errno when called and restores errno
|
aa_policy_cache_unref() saves the value of errno when called and restores errno
|
||||||
before exiting in libapparmor version 2.12 and newer.
|
before exiting in libapparmor version 2.12 and newer.
|
||||||
|
@@ -154,6 +154,7 @@ extern int aa_features_write_to_file(aa_features *features,
|
|||||||
extern bool aa_features_is_equal(aa_features *features1,
|
extern bool aa_features_is_equal(aa_features *features1,
|
||||||
aa_features *features2);
|
aa_features *features2);
|
||||||
extern bool aa_features_supports(aa_features *features, const char *str);
|
extern bool aa_features_supports(aa_features *features, const char *str);
|
||||||
|
extern char *aa_features_id(aa_features *features);
|
||||||
|
|
||||||
typedef struct aa_kernel_interface aa_kernel_interface;
|
typedef struct aa_kernel_interface aa_kernel_interface;
|
||||||
extern int aa_kernel_interface_new(aa_kernel_interface **kernel_interface,
|
extern int aa_kernel_interface_new(aa_kernel_interface **kernel_interface,
|
||||||
@@ -186,12 +187,22 @@ extern int aa_policy_cache_new(aa_policy_cache **policy_cache,
|
|||||||
aa_features *kernel_features,
|
aa_features *kernel_features,
|
||||||
int dirfd, const char *path,
|
int dirfd, const char *path,
|
||||||
uint16_t max_caches);
|
uint16_t max_caches);
|
||||||
|
extern int aa_policy_cache_add_ro_dir(aa_policy_cache *policy_cache, int dirfd,
|
||||||
|
const char *path);
|
||||||
extern aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache);
|
extern aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache);
|
||||||
extern void aa_policy_cache_unref(aa_policy_cache *policy_cache);
|
extern void aa_policy_cache_unref(aa_policy_cache *policy_cache);
|
||||||
|
|
||||||
extern int aa_policy_cache_remove(int dirfd, const char *path);
|
extern int aa_policy_cache_remove(int dirfd, const char *path);
|
||||||
extern int aa_policy_cache_replace_all(aa_policy_cache *policy_cache,
|
extern int aa_policy_cache_replace_all(aa_policy_cache *policy_cache,
|
||||||
aa_kernel_interface *kernel_interface);
|
aa_kernel_interface *kernel_interface);
|
||||||
|
extern int aa_policy_cache_no_dirs(aa_policy_cache *policy_cache);
|
||||||
|
extern char *aa_policy_cache_dir_path(aa_policy_cache *policy_cache, int n);
|
||||||
|
extern int aa_policy_cache_dirfd(aa_policy_cache *policy_cache, int dir);
|
||||||
|
extern int aa_policy_cache_open(aa_policy_cache *policy_cache, const char *name,
|
||||||
|
int flags);
|
||||||
|
extern char *aa_policy_cache_filename(aa_policy_cache *policy_cache, const char *name);
|
||||||
|
extern char *aa_policy_cache_dir_path_preview(aa_features *kernel_features,
|
||||||
|
int dirfd, const char *path);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,8 @@ int _aa_asprintf(char **strp, const char *fmt, ...);
|
|||||||
|
|
||||||
int _aa_dirat_for_each(int dirfd, const char *name, void *data,
|
int _aa_dirat_for_each(int dirfd, const char *name, void *data,
|
||||||
int (* cb)(int, const char *, struct stat *, void *));
|
int (* cb)(int, const char *, struct stat *, void *));
|
||||||
|
int _aa_overlaydirat_for_each(int dirfd[], int n, void *data,
|
||||||
|
int (* cb)(int, const char *, struct stat *, void *));
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -26,13 +26,13 @@ INCLUDES = $(all_includes)
|
|||||||
# For more information, see:
|
# For more information, see:
|
||||||
# http://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
|
# http://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
|
||||||
#
|
#
|
||||||
AA_LIB_CURRENT = 5
|
AA_LIB_CURRENT = 6
|
||||||
AA_LIB_REVISION = 2
|
AA_LIB_REVISION = 0
|
||||||
AA_LIB_AGE = 4
|
AA_LIB_AGE = 5
|
||||||
|
|
||||||
SUFFIXES = .pc.in .pc
|
SUFFIXES = .pc.in .pc
|
||||||
|
|
||||||
BUILT_SOURCES = grammar.h scanner.h af_protos.h
|
BUILT_SOURCES = grammar.h scanner.h af_protos.h PMurHash.h
|
||||||
AM_LFLAGS = -v
|
AM_LFLAGS = -v
|
||||||
AM_YFLAGS = -d -p aalogparse_
|
AM_YFLAGS = -d -p aalogparse_
|
||||||
AM_CFLAGS = -Wall
|
AM_CFLAGS = -Wall
|
||||||
@@ -46,9 +46,9 @@ af_protos.h: /usr/include/netinet/in.h
|
|||||||
LC_ALL=C sed -n -e "/IPPROTO_MAX/d" -e "s/^\#define[ \\t]\\+IPPROTO_\\([A-Z0-9_]\\+\\)\\(.*\\)$$/AA_GEN_PROTO_ENT(\\UIPPROTO_\\1, \"\\L\\1\")/p" $< > $@
|
LC_ALL=C sed -n -e "/IPPROTO_MAX/d" -e "s/^\#define[ \\t]\\+IPPROTO_\\([A-Z0-9_]\\+\\)\\(.*\\)$$/AA_GEN_PROTO_ENT(\\UIPPROTO_\\1, \"\\L\\1\")/p" $< > $@
|
||||||
|
|
||||||
lib_LTLIBRARIES = libapparmor.la
|
lib_LTLIBRARIES = libapparmor.la
|
||||||
noinst_HEADERS = grammar.h parser.h scanner.h af_protos.h private.h
|
noinst_HEADERS = grammar.h parser.h scanner.h af_protos.h private.h PMurHash.h
|
||||||
|
|
||||||
libapparmor_la_SOURCES = grammar.y libaalogparse.c kernel.c scanner.c private.c features.c kernel_interface.c policy_cache.c
|
libapparmor_la_SOURCES = grammar.y libaalogparse.c kernel.c scanner.c private.c features.c kernel_interface.c policy_cache.c PMurHash.c
|
||||||
libapparmor_la_LDFLAGS = -version-info $(AA_LIB_CURRENT):$(AA_LIB_REVISION):$(AA_LIB_AGE) -XCClinker -dynamic -pthread \
|
libapparmor_la_LDFLAGS = -version-info $(AA_LIB_CURRENT):$(AA_LIB_REVISION):$(AA_LIB_AGE) -XCClinker -dynamic -pthread \
|
||||||
-Wl,--version-script=$(top_srcdir)/src/libapparmor.map
|
-Wl,--version-script=$(top_srcdir)/src/libapparmor.map
|
||||||
|
|
||||||
|
317
libraries/libapparmor/src/PMurHash.c
Normal file
317
libraries/libapparmor/src/PMurHash.c
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* MurmurHash3 was written by Austin Appleby, and is placed in the public
|
||||||
|
* domain.
|
||||||
|
*
|
||||||
|
* This implementation was written by Shane Day, and is also public domain.
|
||||||
|
*
|
||||||
|
* This is a portable ANSI C implementation of MurmurHash3_x86_32 (Murmur3A)
|
||||||
|
* with support for progressive processing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
If you want to understand the MurmurHash algorithm you would be much better
|
||||||
|
off reading the original source. Just point your browser at:
|
||||||
|
http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
|
||||||
|
|
||||||
|
|
||||||
|
What this version provides?
|
||||||
|
|
||||||
|
1. Progressive data feeding. Useful when the entire payload to be hashed
|
||||||
|
does not fit in memory or when the data is streamed through the application.
|
||||||
|
Also useful when hashing a number of strings with a common prefix. A partial
|
||||||
|
hash of a prefix string can be generated and reused for each suffix string.
|
||||||
|
|
||||||
|
2. Portability. Plain old C so that it should compile on any old compiler.
|
||||||
|
Both CPU endian and access-alignment neutral, but avoiding inefficient code
|
||||||
|
when possible depending on CPU capabilities.
|
||||||
|
|
||||||
|
3. Drop in. I personally like nice self contained public domain code, making it
|
||||||
|
easy to pilfer without loads of refactoring to work properly in the existing
|
||||||
|
application code & makefile structure and mucking around with licence files.
|
||||||
|
Just copy PMurHash.h and PMurHash.c and you're ready to go.
|
||||||
|
|
||||||
|
|
||||||
|
How does it work?
|
||||||
|
|
||||||
|
We can only process entire 32 bit chunks of input, except for the very end
|
||||||
|
that may be shorter. So along with the partial hash we need to give back to
|
||||||
|
the caller a carry containing up to 3 bytes that we were unable to process.
|
||||||
|
This carry also needs to record the number of bytes the carry holds. I use
|
||||||
|
the low 2 bits as a count (0..3) and the carry bytes are shifted into the
|
||||||
|
high byte in stream order.
|
||||||
|
|
||||||
|
To handle endianess I simply use a macro that reads a uint32_t and define
|
||||||
|
that macro to be a direct read on little endian machines, a read and swap
|
||||||
|
on big endian machines, or a byte-by-byte read if the endianess is unknown.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "PMurHash.h"
|
||||||
|
|
||||||
|
/* I used ugly type names in the header to avoid potential conflicts with
|
||||||
|
* application or system typedefs & defines. Since I'm not including any more
|
||||||
|
* headers below here I can rename these so that the code reads like C99 */
|
||||||
|
#undef uint32_t
|
||||||
|
#define uint32_t MH_UINT32
|
||||||
|
#undef uint8_t
|
||||||
|
#define uint8_t MH_UINT8
|
||||||
|
|
||||||
|
/* MSVC warnings we choose to ignore */
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(disable: 4127) /* conditional expression is constant */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* Endianess, misalignment capabilities and util macros
|
||||||
|
*
|
||||||
|
* The following 3 macros are defined in this section. The other macros defined
|
||||||
|
* are only needed to help derive these 3.
|
||||||
|
*
|
||||||
|
* READ_UINT32(x) Read a little endian unsigned 32-bit int
|
||||||
|
* UNALIGNED_SAFE Defined if READ_UINT32 works on non-word boundaries
|
||||||
|
* ROTL32(x,r) Rotate x left by r bits
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Convention is to define __BYTE_ORDER == to one of these values */
|
||||||
|
#if !defined(__BIG_ENDIAN)
|
||||||
|
#define __BIG_ENDIAN 4321
|
||||||
|
#endif
|
||||||
|
#if !defined(__LITTLE_ENDIAN)
|
||||||
|
#define __LITTLE_ENDIAN 1234
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* I386 */
|
||||||
|
#if defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(i386)
|
||||||
|
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||||
|
#define UNALIGNED_SAFE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* gcc 'may' define __LITTLE_ENDIAN__ or __BIG_ENDIAN__ to 1 (Note the trailing __),
|
||||||
|
* or even _LITTLE_ENDIAN or _BIG_ENDIAN (Note the single _ prefix) */
|
||||||
|
#if !defined(__BYTE_ORDER)
|
||||||
|
#if defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__==1 || defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN==1
|
||||||
|
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||||
|
#elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 || defined(_BIG_ENDIAN) && _BIG_ENDIAN==1
|
||||||
|
#define __BYTE_ORDER __BIG_ENDIAN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* gcc (usually) defines xEL/EB macros for ARM and MIPS endianess */
|
||||||
|
#if !defined(__BYTE_ORDER)
|
||||||
|
#if defined(__ARMEL__) || defined(__MIPSEL__)
|
||||||
|
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||||
|
#endif
|
||||||
|
#if defined(__ARMEB__) || defined(__MIPSEB__)
|
||||||
|
#define __BYTE_ORDER __BIG_ENDIAN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Now find best way we can to READ_UINT32 */
|
||||||
|
#if __BYTE_ORDER==__LITTLE_ENDIAN
|
||||||
|
/* CPU endian matches murmurhash algorithm, so read 32-bit word directly */
|
||||||
|
#define READ_UINT32(ptr) (*((uint32_t*)(ptr)))
|
||||||
|
#elif __BYTE_ORDER==__BIG_ENDIAN
|
||||||
|
/* TODO: Add additional cases below where a compiler provided bswap32 is available */
|
||||||
|
#if defined(__GNUC__) && (__GNUC__>4 || (__GNUC__==4 && __GNUC_MINOR__>=3))
|
||||||
|
#define READ_UINT32(ptr) (__builtin_bswap32(*((uint32_t*)(ptr))))
|
||||||
|
#else
|
||||||
|
/* Without a known fast bswap32 we're just as well off doing this */
|
||||||
|
#define READ_UINT32(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24)
|
||||||
|
#define UNALIGNED_SAFE
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* Unknown endianess so last resort is to read individual bytes */
|
||||||
|
#define READ_UINT32(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24)
|
||||||
|
|
||||||
|
/* Since we're not doing word-reads we can skip the messing about with realignment */
|
||||||
|
#define UNALIGNED_SAFE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Find best way to ROTL32 */
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#include <stdlib.h> /* Microsoft put _rotl declaration in here */
|
||||||
|
#define ROTL32(x,r) _rotl(x,r)
|
||||||
|
#else
|
||||||
|
/* gcc recognises this code and generates a rotate instruction for CPUs with one */
|
||||||
|
#define ROTL32(x,r) (((uint32_t)x << r) | ((uint32_t)x >> (32 - r)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* Core murmurhash algorithm macros */
|
||||||
|
|
||||||
|
#define C1 (0xcc9e2d51)
|
||||||
|
#define C2 (0x1b873593)
|
||||||
|
|
||||||
|
/* This is the main processing body of the algorithm. It operates
|
||||||
|
* on each full 32-bits of input. */
|
||||||
|
#define DOBLOCK(h1, k1) do{ \
|
||||||
|
k1 *= C1; \
|
||||||
|
k1 = ROTL32(k1,15); \
|
||||||
|
k1 *= C2; \
|
||||||
|
\
|
||||||
|
h1 ^= k1; \
|
||||||
|
h1 = ROTL32(h1,13); \
|
||||||
|
h1 = h1*5+0xe6546b64; \
|
||||||
|
}while(0)
|
||||||
|
|
||||||
|
|
||||||
|
/* Append unaligned bytes to carry, forcing hash churn if we have 4 bytes */
|
||||||
|
/* cnt=bytes to process, h1=name of h1 var, c=carry, n=bytes in c, ptr/len=payload */
|
||||||
|
#define DOBYTES(cnt, h1, c, n, ptr, len) do{ \
|
||||||
|
int _i = cnt; \
|
||||||
|
while(_i--) { \
|
||||||
|
c = c>>8 | *ptr++<<24; \
|
||||||
|
n++; len--; \
|
||||||
|
if(n==4) { \
|
||||||
|
DOBLOCK(h1, c); \
|
||||||
|
n = 0; \
|
||||||
|
} \
|
||||||
|
} }while(0)
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Main hashing function. Initialise carry to 0 and h1 to 0 or an initial seed
|
||||||
|
* if wanted. Both ph1 and pcarry are required arguments. */
|
||||||
|
void PMurHash32_Process(uint32_t *ph1, uint32_t *pcarry, const void *key, int len)
|
||||||
|
{
|
||||||
|
uint32_t h1 = *ph1;
|
||||||
|
uint32_t c = *pcarry;
|
||||||
|
|
||||||
|
const uint8_t *ptr = (uint8_t*)key;
|
||||||
|
const uint8_t *end;
|
||||||
|
|
||||||
|
/* Extract carry count from low 2 bits of c value */
|
||||||
|
int n = c & 3;
|
||||||
|
|
||||||
|
#if defined(UNALIGNED_SAFE)
|
||||||
|
/* This CPU handles unaligned word access */
|
||||||
|
|
||||||
|
/* Consume any carry bytes */
|
||||||
|
int i = (4-n) & 3;
|
||||||
|
if(i && i <= len) {
|
||||||
|
DOBYTES(i, h1, c, n, ptr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process 32-bit chunks */
|
||||||
|
end = ptr + len/4*4;
|
||||||
|
for( ; ptr < end ; ptr+=4) {
|
||||||
|
uint32_t k1 = READ_UINT32(ptr);
|
||||||
|
DOBLOCK(h1, k1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /*UNALIGNED_SAFE*/
|
||||||
|
/* This CPU does not handle unaligned word access */
|
||||||
|
|
||||||
|
/* Consume enough so that the next data byte is word aligned */
|
||||||
|
int i = -(long)ptr & 3;
|
||||||
|
if(i && i <= len) {
|
||||||
|
DOBYTES(i, h1, c, n, ptr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're now aligned. Process in aligned blocks. Specialise for each possible carry count */
|
||||||
|
end = ptr + len/4*4;
|
||||||
|
switch(n) { /* how many bytes in c */
|
||||||
|
case 0: /* c=[----] w=[3210] b=[3210]=w c'=[----] */
|
||||||
|
for( ; ptr < end ; ptr+=4) {
|
||||||
|
uint32_t k1 = READ_UINT32(ptr);
|
||||||
|
DOBLOCK(h1, k1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: /* c=[0---] w=[4321] b=[3210]=c>>24|w<<8 c'=[4---] */
|
||||||
|
for( ; ptr < end ; ptr+=4) {
|
||||||
|
uint32_t k1 = c>>24;
|
||||||
|
c = READ_UINT32(ptr);
|
||||||
|
k1 |= c<<8;
|
||||||
|
DOBLOCK(h1, k1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: /* c=[10--] w=[5432] b=[3210]=c>>16|w<<16 c'=[54--] */
|
||||||
|
for( ; ptr < end ; ptr+=4) {
|
||||||
|
uint32_t k1 = c>>16;
|
||||||
|
c = READ_UINT32(ptr);
|
||||||
|
k1 |= c<<16;
|
||||||
|
DOBLOCK(h1, k1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: /* c=[210-] w=[6543] b=[3210]=c>>8|w<<24 c'=[654-] */
|
||||||
|
for( ; ptr < end ; ptr+=4) {
|
||||||
|
uint32_t k1 = c>>8;
|
||||||
|
c = READ_UINT32(ptr);
|
||||||
|
k1 |= c<<24;
|
||||||
|
DOBLOCK(h1, k1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /*UNALIGNED_SAFE*/
|
||||||
|
|
||||||
|
/* Advance over whole 32-bit chunks, possibly leaving 1..3 bytes */
|
||||||
|
len -= len/4*4;
|
||||||
|
|
||||||
|
/* Append any remaining bytes into carry */
|
||||||
|
DOBYTES(len, h1, c, n, ptr, len);
|
||||||
|
|
||||||
|
/* Copy out new running hash and carry */
|
||||||
|
*ph1 = h1;
|
||||||
|
*pcarry = (c & ~0xff) | n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Finalize a hash. To match the original Murmur3A the total_length must be provided */
|
||||||
|
uint32_t PMurHash32_Result(uint32_t h, uint32_t carry, uint32_t total_length)
|
||||||
|
{
|
||||||
|
uint32_t k1;
|
||||||
|
int n = carry & 3;
|
||||||
|
if(n) {
|
||||||
|
k1 = carry >> (4-n)*8;
|
||||||
|
k1 *= C1; k1 = ROTL32(k1,15); k1 *= C2; h ^= k1;
|
||||||
|
}
|
||||||
|
h ^= total_length;
|
||||||
|
|
||||||
|
/* fmix */
|
||||||
|
h ^= h >> 16;
|
||||||
|
h *= 0x85ebca6b;
|
||||||
|
h ^= h >> 13;
|
||||||
|
h *= 0xc2b2ae35;
|
||||||
|
h ^= h >> 16;
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Murmur3A compatable all-at-once */
|
||||||
|
uint32_t PMurHash32(uint32_t seed, const void *key, int len)
|
||||||
|
{
|
||||||
|
uint32_t h1=seed, carry=0;
|
||||||
|
PMurHash32_Process(&h1, &carry, key, len);
|
||||||
|
return PMurHash32_Result(h1, carry, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Provide an API suitable for smhasher */
|
||||||
|
void PMurHash32_test(const void *key, int len, uint32_t seed, void *out)
|
||||||
|
{
|
||||||
|
uint32_t h1=seed, carry=0;
|
||||||
|
const uint8_t *ptr = (uint8_t*)key;
|
||||||
|
const uint8_t *end = ptr + len;
|
||||||
|
|
||||||
|
#if 0 /* Exercise the progressive processing */
|
||||||
|
while(ptr < end) {
|
||||||
|
//const uint8_t *mid = ptr + rand()%(end-ptr)+1;
|
||||||
|
const uint8_t *mid = ptr + (rand()&0xF);
|
||||||
|
mid = mid<end?mid:end;
|
||||||
|
PMurHash32_Process(&h1, &carry, ptr, mid-ptr);
|
||||||
|
ptr = mid;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
PMurHash32_Process(&h1, &carry, ptr, (int)(end-ptr));
|
||||||
|
#endif
|
||||||
|
h1 = PMurHash32_Result(h1, carry, len);
|
||||||
|
*(uint32_t*)out = h1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
64
libraries/libapparmor/src/PMurHash.h
Normal file
64
libraries/libapparmor/src/PMurHash.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* MurmurHash3 was written by Austin Appleby, and is placed in the public
|
||||||
|
* domain.
|
||||||
|
*
|
||||||
|
* This implementation was written by Shane Day, and is also public domain.
|
||||||
|
*
|
||||||
|
* This is a portable ANSI C implementation of MurmurHash3_x86_32 (Murmur3A)
|
||||||
|
* with support for progressive processing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
/* Determine what native type to use for uint32_t */
|
||||||
|
|
||||||
|
/* We can't use the name 'uint32_t' here because it will conflict with
|
||||||
|
* any version provided by the system headers or application. */
|
||||||
|
|
||||||
|
/* First look for special cases */
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define MH_UINT32 unsigned long
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If the compiler says it's C99 then take its word for it */
|
||||||
|
#if !defined(MH_UINT32) && ( \
|
||||||
|
defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L )
|
||||||
|
#include <stdint.h>
|
||||||
|
#define MH_UINT32 uint32_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Otherwise try testing against max value macros from limit.h */
|
||||||
|
#if !defined(MH_UINT32)
|
||||||
|
#include <limits.h>
|
||||||
|
#if (USHRT_MAX == 0xffffffffUL)
|
||||||
|
#define MH_UINT32 unsigned short
|
||||||
|
#elif (UINT_MAX == 0xffffffffUL)
|
||||||
|
#define MH_UINT32 unsigned int
|
||||||
|
#elif (ULONG_MAX == 0xffffffffUL)
|
||||||
|
#define MH_UINT32 unsigned long
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MH_UINT32)
|
||||||
|
#error Unable to determine type name for unsigned 32-bit int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* I'm yet to work on a platform where 'unsigned char' is not 8 bits */
|
||||||
|
#define MH_UINT8 unsigned char
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
/* Prototypes */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void PMurHash32_Process(MH_UINT32 *ph1, MH_UINT32 *pcarry, const void *key, int len);
|
||||||
|
MH_UINT32 PMurHash32_Result(MH_UINT32 h1, MH_UINT32 carry, MH_UINT32 total_length);
|
||||||
|
MH_UINT32 PMurHash32(MH_UINT32 seed, const void *key, int len);
|
||||||
|
|
||||||
|
void PMurHash32_test(const void *key, int len, MH_UINT32 seed, void *out);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014
|
* Copyright (c) 2014-2017
|
||||||
* Canonical, Ltd. (All rights reserved)
|
* Canonical, Ltd. (All rights reserved)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -31,13 +32,16 @@
|
|||||||
#include <sys/apparmor.h>
|
#include <sys/apparmor.h>
|
||||||
|
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
#include "PMurHash.h"
|
||||||
|
|
||||||
#define FEATURES_FILE "/sys/kernel/security/apparmor/features"
|
#define FEATURES_FILE "/sys/kernel/security/apparmor/features"
|
||||||
|
|
||||||
|
#define HASH_SIZE (8 + 1) /* 32 bits binary to hex + NUL terminator */
|
||||||
#define STRING_SIZE 8192
|
#define STRING_SIZE 8192
|
||||||
|
|
||||||
struct aa_features {
|
struct aa_features {
|
||||||
unsigned int ref_count;
|
unsigned int ref_count;
|
||||||
|
char hash[HASH_SIZE];
|
||||||
char string[STRING_SIZE];
|
char string[STRING_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -205,6 +209,29 @@ static ssize_t load_features_dir(int dirfd, const char *path,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int init_features_hash(aa_features *features)
|
||||||
|
{
|
||||||
|
const char *string = features->string;
|
||||||
|
uint32_t seed = 5381;
|
||||||
|
uint32_t hash = seed, carry = 0;
|
||||||
|
size_t len = strlen(string);
|
||||||
|
|
||||||
|
/* portable murmur3 hash
|
||||||
|
* https://github.com/aappleby/smhasher/wiki/MurmurHash3
|
||||||
|
*/
|
||||||
|
PMurHash32_Process(&hash, &carry, features, len);
|
||||||
|
hash = PMurHash32_Result(hash, carry, len);
|
||||||
|
|
||||||
|
if (snprintf(features->hash, HASH_SIZE,
|
||||||
|
"%08" PRIx32, hash) >= HASH_SIZE) {
|
||||||
|
errno = ENOBUFS;
|
||||||
|
PERROR("Hash buffer full.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static bool islbrace(int c)
|
static bool islbrace(int c)
|
||||||
{
|
{
|
||||||
return c == '{';
|
return c == '{';
|
||||||
@@ -408,6 +435,14 @@ int aa_features_new(aa_features **features, int dirfd, const char *path)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (init_features_hash(f) == -1) {
|
||||||
|
int save = errno;
|
||||||
|
|
||||||
|
aa_features_unref(f);
|
||||||
|
errno = save;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
*features = f;
|
*features = f;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -443,6 +478,15 @@ int aa_features_new_from_string(aa_features **features,
|
|||||||
|
|
||||||
memcpy(f->string, string, size);
|
memcpy(f->string, string, size);
|
||||||
f->string[size] = '\0';
|
f->string[size] = '\0';
|
||||||
|
|
||||||
|
if (init_features_hash(f) == -1) {
|
||||||
|
int save = errno;
|
||||||
|
|
||||||
|
aa_features_unref(f);
|
||||||
|
errno = save;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
*features = f;
|
*features = f;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -577,3 +621,21 @@ bool aa_features_supports(aa_features *features, const char *str)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* aa_features_id - provides unique identifier for an aa_features object
|
||||||
|
* @features: the features
|
||||||
|
*
|
||||||
|
* Allocates and returns a string representation of an identifier that can
|
||||||
|
* be used to uniquely identify an aa_features object. The mechanism for
|
||||||
|
* generating the string representation is internal to libapparmor and
|
||||||
|
* subject to change but an example implementation is applying a hash
|
||||||
|
* function to the features string.
|
||||||
|
*
|
||||||
|
* Returns: a string identifying @features which must be freed by the
|
||||||
|
* caller or NULL, with errno set, upon error
|
||||||
|
*/
|
||||||
|
char *aa_features_id(aa_features *features)
|
||||||
|
{
|
||||||
|
return strdup(features->hash);
|
||||||
|
}
|
||||||
|
@@ -95,6 +95,19 @@ APPARMOR_2.11 {
|
|||||||
*;
|
*;
|
||||||
} APPARMOR_2.10;
|
} APPARMOR_2.10;
|
||||||
|
|
||||||
|
APPARMOR_2.13 {
|
||||||
|
global:
|
||||||
|
aa_policy_cache_dir_path;
|
||||||
|
aa_policy_cache_dir_path_preview;
|
||||||
|
aa_policy_cache_no_dirs;
|
||||||
|
aa_policy_cache_dirfd;
|
||||||
|
aa_policy_cache_open;
|
||||||
|
aa_policy_cache_filename;
|
||||||
|
aa_features_id;
|
||||||
|
local:
|
||||||
|
*;
|
||||||
|
} APPARMOR_2.11;
|
||||||
|
|
||||||
PRIVATE {
|
PRIVATE {
|
||||||
global:
|
global:
|
||||||
_aa_is_blacklisted;
|
_aa_is_blacklisted;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014
|
* Copyright (c) 2014-2017
|
||||||
* Canonical, Ltd. (All rights reserved)
|
* Canonical, Ltd. (All rights reserved)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
@@ -16,8 +16,11 @@
|
|||||||
* Ltd.
|
* Ltd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -29,31 +32,155 @@
|
|||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
|
||||||
#define CACHE_FEATURES_FILE ".features"
|
#define CACHE_FEATURES_FILE ".features"
|
||||||
|
#define MAX_POLICY_CACHE_OVERLAY_DIRS 4
|
||||||
|
|
||||||
struct aa_policy_cache {
|
struct aa_policy_cache {
|
||||||
unsigned int ref_count;
|
unsigned int ref_count;
|
||||||
aa_features *features;
|
aa_features *features;
|
||||||
aa_features *kernel_features;
|
aa_features *kernel_features;
|
||||||
int dirfd;
|
int n;
|
||||||
|
int dirfd[MAX_POLICY_CACHE_OVERLAY_DIRS];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int clear_cache_cb(int dirfd, const char *path, struct stat *st,
|
static int clear_cache_cb(int dirfd, const char *path, struct stat *st,
|
||||||
void *data unused)
|
void *data unused)
|
||||||
{
|
{
|
||||||
/* remove regular files */
|
if (S_ISREG(st->st_mode)) {
|
||||||
if (S_ISREG(st->st_mode))
|
/* remove regular files */
|
||||||
return unlinkat(dirfd, path, 0);
|
return unlinkat(dirfd, path, 0);
|
||||||
|
} else if (S_ISDIR(st->st_mode)) {
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
retval = _aa_dirat_for_each(dirfd, path, NULL, clear_cache_cb);
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
return unlinkat(dirfd, path, AT_REMOVEDIR);
|
||||||
|
}
|
||||||
|
|
||||||
/* do nothing with other file types */
|
/* do nothing with other file types */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct replace_all_cb_data {
|
||||||
|
aa_policy_cache *policy_cache;
|
||||||
|
aa_kernel_interface *kernel_interface;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int replace_all_cb(int dirfd, const char *name, struct stat *st,
|
||||||
|
void *cb_data)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
if (S_ISLNK(st->st_mode)) {
|
||||||
|
/*
|
||||||
|
* symlinks in that cache are used to track file merging.
|
||||||
|
* In the scanned overlay situation they can be skipped
|
||||||
|
* as the combined entry will be one of none skipped
|
||||||
|
* entries
|
||||||
|
*/
|
||||||
|
} else if (S_ISREG(st->st_mode) && st->st_size == 0) {
|
||||||
|
/*
|
||||||
|
* empty file in the cache dir is used as a whiteout
|
||||||
|
* to hide files in a lower layer. skip
|
||||||
|
*/
|
||||||
|
} else if (!S_ISDIR(st->st_mode) && !_aa_is_blacklisted(name)) {
|
||||||
|
struct replace_all_cb_data *data;
|
||||||
|
|
||||||
|
data = (struct replace_all_cb_data *) cb_data;
|
||||||
|
retval = aa_kernel_interface_replace_policy_from_file(data->kernel_interface,
|
||||||
|
dirfd,
|
||||||
|
name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *path_from_fd(int fd)
|
||||||
|
{
|
||||||
|
autofree char *proc_path = NULL;
|
||||||
|
autoclose int proc_fd = -1;
|
||||||
|
struct stat proc_stat;
|
||||||
|
char *path;
|
||||||
|
ssize_t size, path_len;
|
||||||
|
|
||||||
|
if (asprintf(&proc_path, "/proc/self/fd/%d", fd) == -1) {
|
||||||
|
proc_path = NULL;
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc_fd = open(proc_path, O_RDONLY | O_CLOEXEC | O_PATH | O_NOFOLLOW);
|
||||||
|
if (proc_fd == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (fstat(proc_fd, &proc_stat) == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!S_ISLNK(proc_stat.st_mode)) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = proc_stat.st_size;
|
||||||
|
repeat:
|
||||||
|
path = malloc(size + 1);
|
||||||
|
if (!path)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Since 2.6.39, symlink file descriptors opened with
|
||||||
|
* (O_PATH | O_NOFOLLOW) can be used as the dirfd with an empty string
|
||||||
|
* as the path. readlinkat() will operate on the symlink inode.
|
||||||
|
*/
|
||||||
|
path_len = readlinkat(proc_fd, "", path, size);
|
||||||
|
if (path_len == -1)
|
||||||
|
return NULL;
|
||||||
|
if (path_len == size) {
|
||||||
|
free(path);
|
||||||
|
size = size * 2;
|
||||||
|
goto repeat;
|
||||||
|
}
|
||||||
|
path[path_len] = '\0';
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cache_check_features(int dirfd, const char *cache_name,
|
||||||
|
aa_features *features)
|
||||||
|
{
|
||||||
|
aa_features *local_features = NULL;
|
||||||
|
autofree char *name = NULL;
|
||||||
|
bool rc;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = asprintf(&name, "%s/%s", cache_name, CACHE_FEATURES_FILE);
|
||||||
|
if (len == -1) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verify that cache dir .features matches */
|
||||||
|
if (aa_features_new(&local_features, dirfd, name)) {
|
||||||
|
PDEBUG("could not setup new features object for dirfd '%d' '%s'\n", dirfd, name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = aa_features_is_equal(local_features, features);
|
||||||
|
aa_features_unref(local_features);
|
||||||
|
if (!rc) {
|
||||||
|
errno = EEXIST;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int create_cache(aa_policy_cache *policy_cache, aa_features *features)
|
static int create_cache(aa_policy_cache *policy_cache, aa_features *features)
|
||||||
{
|
{
|
||||||
if (aa_policy_cache_remove(policy_cache->dirfd, "."))
|
if (aa_policy_cache_remove(policy_cache->dirfd[0], "."))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (aa_features_write_to_file(features, policy_cache->dirfd,
|
if (aa_features_write_to_file(features, policy_cache->dirfd[0],
|
||||||
CACHE_FEATURES_FILE) == -1)
|
CACHE_FEATURES_FILE) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -65,51 +192,171 @@ static int create_cache(aa_policy_cache *policy_cache, aa_features *features)
|
|||||||
static int init_cache_features(aa_policy_cache *policy_cache,
|
static int init_cache_features(aa_policy_cache *policy_cache,
|
||||||
aa_features *kernel_features, bool create)
|
aa_features *kernel_features, bool create)
|
||||||
{
|
{
|
||||||
bool call_create_cache = false;
|
if (cache_check_features(policy_cache->dirfd[0], ".",
|
||||||
|
kernel_features)) {
|
||||||
if (aa_features_new(&policy_cache->features, policy_cache->dirfd,
|
/* EEXIST must come before ENOENT for short circuit eval */
|
||||||
CACHE_FEATURES_FILE)) {
|
if (!create || errno == EEXIST || errno != ENOENT)
|
||||||
policy_cache->features = NULL;
|
|
||||||
if (!create || errno != ENOENT)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* The cache directory needs to be created */
|
return create_cache(policy_cache, kernel_features);
|
||||||
call_create_cache = true;
|
|
||||||
} else if (!aa_features_is_equal(policy_cache->features,
|
|
||||||
kernel_features)) {
|
|
||||||
if (!create) {
|
|
||||||
errno = EEXIST;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The cache directory needs to be refreshed */
|
|
||||||
call_create_cache = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return call_create_cache ?
|
|
||||||
create_cache(policy_cache, kernel_features) : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct replace_all_cb_data {
|
struct miss_cb_data {
|
||||||
aa_policy_cache *policy_cache;
|
aa_features *features;
|
||||||
aa_kernel_interface *kernel_interface;
|
const char *path;
|
||||||
|
char *pattern;
|
||||||
|
char *cache_name; /* return */
|
||||||
|
long n;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int replace_all_cb(int dirfd unused, const char *name, struct stat *st,
|
/* called on cache collision or miss where cache isn't present */
|
||||||
void *cb_data)
|
static int cache_miss_cb(int dirfd, const struct dirent *ent, void *arg)
|
||||||
{
|
{
|
||||||
int retval = 0;
|
struct miss_cb_data *data = arg;
|
||||||
|
char *cache_name, *pos, *tmp;
|
||||||
|
long n;
|
||||||
|
int len;
|
||||||
|
|
||||||
if (!S_ISDIR(st->st_mode) && !_aa_is_blacklisted(name)) {
|
/* TODO: update to tighter pattern match of just trailing #s */
|
||||||
struct replace_all_cb_data *data;
|
if (fnmatch(data->pattern, ent->d_name, 0))
|
||||||
|
return 0;
|
||||||
|
|
||||||
data = (struct replace_all_cb_data *) cb_data;
|
/* entry matches <feature_id>.<n> pattern */
|
||||||
retval = aa_kernel_interface_replace_policy_from_file(data->kernel_interface,
|
len = asprintf(&cache_name, "%s/%s", data->path, ent->d_name);
|
||||||
data->policy_cache->dirfd,
|
if (len == -1) {
|
||||||
name);
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!cache_check_features(dirfd, cache_name, data->features) || errno == ENOENT) {
|
||||||
|
/* found cache dir matching pattern */
|
||||||
|
data->cache_name = cache_name;
|
||||||
|
/* return 1 to stop iteration and signal dir found */
|
||||||
|
return 1;
|
||||||
|
} else if (errno != EEXIST) {
|
||||||
|
PDEBUG("cache_check_features() failed for dirfd '%d' '%s'\n", dirfd, cache_name);
|
||||||
|
free(cache_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
free(cache_name);
|
||||||
|
|
||||||
|
/* check the cache dir # */
|
||||||
|
pos = strchr(ent->d_name, '.');
|
||||||
|
n = strtol(pos+1, &tmp, 10);
|
||||||
|
if (n == LONG_MIN || n == LONG_MAX || tmp == pos + 1)
|
||||||
|
return -1;
|
||||||
|
if (n > data->n)
|
||||||
|
data->n = n;
|
||||||
|
|
||||||
|
/* continue processing */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* will return cache_path on error if there is a collision */
|
||||||
|
static int cache_dir_from_path_and_features(char **cache_path,
|
||||||
|
int dirfd, const char *path,
|
||||||
|
aa_features *features)
|
||||||
|
{
|
||||||
|
autofree const char *features_id = NULL;
|
||||||
|
char *cache_dir;
|
||||||
|
size_t len;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
features_id = aa_features_id(features);
|
||||||
|
if (!features_id)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
len = asprintf(&cache_dir, "%s/%s.0", path, features_id);
|
||||||
|
if (len == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!cache_check_features(dirfd, cache_dir, features) || errno == ENOENT) {
|
||||||
|
PDEBUG("cache_dir_from_path_and_features() found '%s'\n", cache_dir);
|
||||||
|
*cache_path = cache_dir;
|
||||||
|
return 0;
|
||||||
|
} else if (errno != EEXIST) {
|
||||||
|
PDEBUG("cache_check_features() failed for dirfd '%d' %s\n", dirfd, cache_dir);
|
||||||
|
free(cache_dir);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
PDEBUG("Cache collision '%s' falling back to next dir on fd '%d' path %s", cache_dir, dirfd, path);
|
||||||
|
free(cache_dir);
|
||||||
|
|
||||||
|
struct miss_cb_data data = {
|
||||||
|
.features = features,
|
||||||
|
.path = path,
|
||||||
|
.cache_name = NULL,
|
||||||
|
.n = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (asprintf(&data.pattern, "%s.*", features_id) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
rc = _aa_dirat_for_each2(dirfd, path, &data, cache_miss_cb);
|
||||||
|
free(data.pattern);
|
||||||
|
if (rc == 1) {
|
||||||
|
/* found matching feature dir */
|
||||||
|
PDEBUG("cache_dir_from_path_and_features() callback found '%s'\n", data.cache_name);
|
||||||
|
*cache_path = data.cache_name;
|
||||||
|
return 0;
|
||||||
|
} else if (rc)
|
||||||
|
return -1;
|
||||||
|
/* no dir found use 1 higher than highest dir n searched */
|
||||||
|
len = asprintf(&cache_dir, "%s/%s.%d", path, features_id, data.n + 1);
|
||||||
|
if (len == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PDEBUG("Cache collision no dir found using %d + 1 = %s\n", data.n + 1, cache_dir);
|
||||||
|
*cache_path = cache_dir;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int open_or_create_cache_dir(aa_features *features, int dirfd,
|
||||||
|
const char *path, bool create)
|
||||||
|
{
|
||||||
|
autofree char *cache_dir = NULL;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (cache_dir_from_path_and_features(&cache_dir, dirfd, path,
|
||||||
|
features))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
open:
|
||||||
|
fd = openat(dirfd, cache_dir, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
|
||||||
|
if (fd < 0) {
|
||||||
|
/* does the dir exist? */
|
||||||
|
if (create && errno == ENOENT) {
|
||||||
|
/**
|
||||||
|
* 1) Attempt to create the cache location, such as
|
||||||
|
* /etc/apparmor.d/cache.d/
|
||||||
|
* 2) Attempt to create the cache directory, for the
|
||||||
|
* passed in aa_features, such as
|
||||||
|
* /etc/apparmor.d/cache.d/<features_id>/
|
||||||
|
* 3) Try to reopen the cache directory
|
||||||
|
*/
|
||||||
|
if (mkdirat(fd, path, 0700) == -1 &&
|
||||||
|
errno != EEXIST) {
|
||||||
|
PERROR("Can't create cache location '%s': %m\n",
|
||||||
|
path);
|
||||||
|
} else if (mkdirat(dirfd, cache_dir, 0700) == -1 &&
|
||||||
|
errno != EEXIST) {
|
||||||
|
PERROR("Can't create cache directory '%s': %m\n",
|
||||||
|
cache_dir);
|
||||||
|
} else {
|
||||||
|
goto open;
|
||||||
|
}
|
||||||
|
} else if (create) {
|
||||||
|
PERROR("Can't update cache directory '%s': %m\n", cache_dir);
|
||||||
|
} else {
|
||||||
|
PDEBUG("Cache directory '%s' does not exist\n", cache_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,6 +382,8 @@ int aa_policy_cache_new(aa_policy_cache **policy_cache,
|
|||||||
{
|
{
|
||||||
aa_policy_cache *pc;
|
aa_policy_cache *pc;
|
||||||
bool create = max_caches > 0;
|
bool create = max_caches > 0;
|
||||||
|
autofree const char *features_id = NULL;
|
||||||
|
int i, fd;
|
||||||
|
|
||||||
*policy_cache = NULL;
|
*policy_cache = NULL;
|
||||||
|
|
||||||
@@ -143,55 +392,72 @@ int aa_policy_cache_new(aa_policy_cache **policy_cache,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_caches > 1) {
|
/* TODO: currently no reaping of caches in excess of max_caches */
|
||||||
errno = ENOTSUP;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pc = calloc(1, sizeof(*pc));
|
pc = calloc(1, sizeof(*pc));
|
||||||
if (!pc) {
|
if (!pc) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pc->dirfd = -1;
|
pc->n = 0;
|
||||||
|
for (i = 0; i < MAX_POLICY_CACHE_OVERLAY_DIRS; i++)
|
||||||
|
pc->dirfd[i] = -1;
|
||||||
aa_policy_cache_ref(pc);
|
aa_policy_cache_ref(pc);
|
||||||
|
|
||||||
open:
|
|
||||||
pc->dirfd = openat(dirfd, path, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
|
|
||||||
if (pc->dirfd < 0) {
|
|
||||||
/* does the dir exist? */
|
|
||||||
if (create && errno == ENOENT) {
|
|
||||||
if (mkdirat(dirfd, path, 0700) == 0)
|
|
||||||
goto open;
|
|
||||||
PERROR("Can't create cache directory '%s': %m\n", path);
|
|
||||||
} else if (create) {
|
|
||||||
PERROR("Can't update cache directory '%s': %m\n", path);
|
|
||||||
} else {
|
|
||||||
PDEBUG("Cache directory '%s' does not exist\n", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
aa_policy_cache_unref(pc);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kernel_features) {
|
if (kernel_features) {
|
||||||
aa_features_ref(kernel_features);
|
aa_features_ref(kernel_features);
|
||||||
} else if (aa_features_new_from_kernel(&kernel_features) == -1) {
|
} else if (aa_features_new_from_kernel(&kernel_features) == -1) {
|
||||||
aa_policy_cache_unref(pc);
|
aa_policy_cache_unref(pc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pc->kernel_features = kernel_features;
|
pc->features = kernel_features;
|
||||||
|
|
||||||
|
fd = open_or_create_cache_dir(kernel_features, dirfd, path, create);
|
||||||
|
if (fd == -1) {
|
||||||
|
aa_policy_cache_unref(pc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pc->dirfd[0] = fd;
|
||||||
|
pc->n = 1;
|
||||||
|
|
||||||
if (init_cache_features(pc, kernel_features, create)) {
|
if (init_cache_features(pc, kernel_features, create)) {
|
||||||
|
PDEBUG("%s: failed init_cache_features for dirfd '%d' name '%s' opened as pc->dirfd '%d'\n", __FUNCTION__, dirfd, cache_dir, pc->dirfd);
|
||||||
aa_policy_cache_unref(pc);
|
aa_policy_cache_unref(pc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDEBUG("%s: created policy_cache for dirfd '%d' name '%s' opened as pc->dirfd '%d'\n", __FUNCTION__, dirfd, cache_dir, pc->dirfd);
|
||||||
*policy_cache = pc;
|
*policy_cache = pc;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* aa_policy_cache_add_ro_dir - add an readonly dir layer to the policy cache
|
||||||
|
* @policy_cache: policy_cache to add the readonly dir to
|
||||||
|
* @dirfd: directory file descriptor or AT_FDCWD (see openat(2))
|
||||||
|
* @path: path to the readonly policy cache
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error with errno set
|
||||||
|
*/
|
||||||
|
|
||||||
|
int aa_policy_cache_add_ro_dir(aa_policy_cache *policy_cache, int dirfd,
|
||||||
|
const char *path)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (policy_cache->n >= MAX_POLICY_CACHE_OVERLAY_DIRS) {
|
||||||
|
errno = ENOSPC;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fd = open_or_create_cache_dir(policy_cache->features, dirfd, path,
|
||||||
|
false);
|
||||||
|
if (fd == -1)
|
||||||
|
return -1;
|
||||||
|
policy_cache->dirfd[policy_cache->n++] = fd;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* aa_policy_cache_ref - increments the ref count of an aa_policy_cache object
|
* aa_policy_cache_ref - increments the ref count of an aa_policy_cache object
|
||||||
* @policy_cache: the policy_cache
|
* @policy_cache: the policy_cache
|
||||||
@@ -210,13 +476,14 @@ aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache)
|
|||||||
*/
|
*/
|
||||||
void aa_policy_cache_unref(aa_policy_cache *policy_cache)
|
void aa_policy_cache_unref(aa_policy_cache *policy_cache)
|
||||||
{
|
{
|
||||||
int save = errno;
|
int i, save = errno;
|
||||||
|
|
||||||
if (policy_cache && atomic_dec_and_test(&policy_cache->ref_count)) {
|
if (policy_cache && atomic_dec_and_test(&policy_cache->ref_count)) {
|
||||||
aa_features_unref(policy_cache->features);
|
aa_features_unref(policy_cache->features);
|
||||||
aa_features_unref(policy_cache->kernel_features);
|
for (i = 0; i < MAX_POLICY_CACHE_OVERLAY_DIRS; i++) {
|
||||||
if (policy_cache->dirfd != -1)
|
if (policy_cache->dirfd[i] != -1)
|
||||||
close(policy_cache->dirfd);
|
close(policy_cache->dirfd[i]);
|
||||||
|
}
|
||||||
free(policy_cache);
|
free(policy_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +521,7 @@ int aa_policy_cache_replace_all(aa_policy_cache *policy_cache,
|
|||||||
if (kernel_interface) {
|
if (kernel_interface) {
|
||||||
aa_kernel_interface_ref(kernel_interface);
|
aa_kernel_interface_ref(kernel_interface);
|
||||||
} else if (aa_kernel_interface_new(&kernel_interface,
|
} else if (aa_kernel_interface_new(&kernel_interface,
|
||||||
policy_cache->kernel_features,
|
policy_cache->features,
|
||||||
NULL) == -1) {
|
NULL) == -1) {
|
||||||
kernel_interface = NULL;
|
kernel_interface = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -262,10 +529,158 @@ int aa_policy_cache_replace_all(aa_policy_cache *policy_cache,
|
|||||||
|
|
||||||
cb_data.policy_cache = policy_cache;
|
cb_data.policy_cache = policy_cache;
|
||||||
cb_data.kernel_interface = kernel_interface;
|
cb_data.kernel_interface = kernel_interface;
|
||||||
retval = _aa_dirat_for_each(policy_cache->dirfd, ".", &cb_data,
|
retval = _aa_overlaydirat_for_each(policy_cache->dirfd, policy_cache->n,
|
||||||
replace_all_cb);
|
&cb_data, replace_all_cb);
|
||||||
|
|
||||||
aa_kernel_interface_unref(kernel_interface);
|
aa_kernel_interface_unref(kernel_interface);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* aa_policy_cache_no_dirs - return the number of dirs making up the cache
|
||||||
|
* @policy_cache: the policy_cache
|
||||||
|
*
|
||||||
|
* Returns: The number of directories that the policy cache is composed of
|
||||||
|
*/
|
||||||
|
int aa_policy_cache_no_dirs(aa_policy_cache *policy_cache)
|
||||||
|
{
|
||||||
|
return policy_cache->n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* aa_policy_cache_dir_path - returns the path to the aa_policy_cache directory
|
||||||
|
* @policy_cache: the policy_cache
|
||||||
|
* @dir: which dir in the policy cache to return the name of
|
||||||
|
*
|
||||||
|
* Returns: The path to the policy cache directory on success, NULL on
|
||||||
|
* error with errno set.
|
||||||
|
*/
|
||||||
|
char *aa_policy_cache_dir_path(aa_policy_cache *policy_cache, int dir)
|
||||||
|
{
|
||||||
|
char *path = NULL;
|
||||||
|
|
||||||
|
if (dir < 0 || dir >= policy_cache->n) {
|
||||||
|
PERROR("aa_policy_cache directory: %d does not exist\n", dir);
|
||||||
|
errno = ERANGE;
|
||||||
|
} else {
|
||||||
|
path = path_from_fd(policy_cache->dirfd[dir]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path)
|
||||||
|
PERROR("Can't return the path to the aa_policy_cache directory: %m\n");
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* aa_policy_cache_dirfd - returns the dirfd for a aa_policy_cache directory
|
||||||
|
* @policy_cache: the policy_cache
|
||||||
|
* @dir: which dir in the policy cache to return the dirfd of
|
||||||
|
*
|
||||||
|
* Returns: The dirfd to the @dir policy cache directory on success, -1 on
|
||||||
|
* error with errno set.
|
||||||
|
*
|
||||||
|
* caller is responsible for closing the returned dirfd
|
||||||
|
*/
|
||||||
|
int aa_policy_cache_dirfd(aa_policy_cache *policy_cache, int dir)
|
||||||
|
{
|
||||||
|
if (dir < 0 || dir >= policy_cache->n) {
|
||||||
|
PERROR("aa_policy_cache directory: %d does not exist\n", dir);
|
||||||
|
errno = ERANGE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dup(policy_cache->dirfd[dir]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open cache file corresponding to name */
|
||||||
|
int aa_policy_cache_open(aa_policy_cache *policy_cache, const char *name,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
int i, fd;
|
||||||
|
|
||||||
|
for (i = 0; i < policy_cache->n; i++) {
|
||||||
|
fd = openat(policy_cache->dirfd[i], name, flags);
|
||||||
|
if (fd != -1)
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *aa_policy_cache_filename(aa_policy_cache *policy_cache, const char *name)
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
autoclose int fd = aa_policy_cache_open(policy_cache, name, O_RDONLY);
|
||||||
|
|
||||||
|
if (fd == -1)
|
||||||
|
return NULL;
|
||||||
|
path = path_from_fd(fd);
|
||||||
|
if (!path)
|
||||||
|
PERROR("Can't return the path to the aa_policy_cache cachename: %m\n");
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* aa_policy_cache_dir_path_preview - returns the path to the aa_policy_cache directory
|
||||||
|
* @kernel_features: features representing a kernel (may be NULL if you want to
|
||||||
|
* use the features of the currently running kernel)
|
||||||
|
* @dirfd: directory file descriptor or AT_FDCWD (see openat(2))
|
||||||
|
* @path: path to the policy cache
|
||||||
|
*
|
||||||
|
* Returns: The path to the policy cache directory on success, NULL on
|
||||||
|
* error with errno set.
|
||||||
|
*/
|
||||||
|
char *aa_policy_cache_dir_path_preview(aa_features *kernel_features,
|
||||||
|
int dirfd, const char *path)
|
||||||
|
{
|
||||||
|
autofree char *cache_loc = NULL;
|
||||||
|
autofree char *cache_dir = NULL;
|
||||||
|
char *dir_path;
|
||||||
|
|
||||||
|
if (kernel_features) {
|
||||||
|
aa_features_ref(kernel_features);
|
||||||
|
} else if (aa_features_new_from_kernel(&kernel_features) == -1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leave cache_loc set to NULL if dirfd is AT_FDCWD and handle a
|
||||||
|
* NULL cache_loc in the asprintf() below
|
||||||
|
*/
|
||||||
|
if (dirfd != AT_FDCWD) {
|
||||||
|
cache_loc = path_from_fd(dirfd);
|
||||||
|
if (!cache_loc) {
|
||||||
|
int save = errno;
|
||||||
|
|
||||||
|
PERROR("Can't return the path to the aa_policy_cache cache location: %m\n");
|
||||||
|
aa_features_unref(kernel_features);
|
||||||
|
errno = save;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PDEBUG("Looking up cachedir path for AT_FDCWD\n");
|
||||||
|
if (cache_dir_from_path_and_features(&cache_dir, dirfd, path,
|
||||||
|
kernel_features)) {
|
||||||
|
int save = errno;
|
||||||
|
|
||||||
|
PERROR("Can't return the path to the aa_policy_cache directory: %m\n");
|
||||||
|
aa_features_unref(kernel_features);
|
||||||
|
errno = save;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
aa_features_unref(kernel_features);
|
||||||
|
|
||||||
|
if (asprintf(&dir_path, "%s%s%s",
|
||||||
|
cache_loc ? : "", cache_loc ? "/" : "", cache_dir) == -1) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDEBUG("aa_policy_cache_dir_path_preview() returning '%s'\n", dir_path);
|
||||||
|
return dir_path;
|
||||||
|
}
|
||||||
|
@@ -56,6 +56,10 @@ static struct ignored_suffix_t ignored_suffixes[] = {
|
|||||||
{ ".dpkg-old", 9, 1 },
|
{ ".dpkg-old", 9, 1 },
|
||||||
{ ".dpkg-dist", 10, 1 },
|
{ ".dpkg-dist", 10, 1 },
|
||||||
{ ".dpkg-bak", 9, 1 },
|
{ ".dpkg-bak", 9, 1 },
|
||||||
|
{ ".dpkg-remove", 12, 1 },
|
||||||
|
/* Archlinux packaging files */
|
||||||
|
{ ".pacsave", 8, 1 },
|
||||||
|
{ ".pacnew", 7, 1 },
|
||||||
/* RPM packaging files have traditionally not been silently
|
/* RPM packaging files have traditionally not been silently
|
||||||
ignored */
|
ignored */
|
||||||
{ ".rpmnew", 7, 0 },
|
{ ".rpmnew", 7, 0 },
|
||||||
@@ -178,6 +182,181 @@ static int dot_or_dot_dot_filter(const struct dirent *ent)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* stops on first error, can use errno or return value to communicate
|
||||||
|
* the goal is to use this to replace _aa_dirat_for_each, but that will
|
||||||
|
* be a different patch.
|
||||||
|
*/
|
||||||
|
int _aa_dirat_for_each2(int dirfd, const char *name, void *data,
|
||||||
|
int (* cb)(int, const struct dirent *, void *))
|
||||||
|
{
|
||||||
|
autoclose int cb_dirfd = -1;
|
||||||
|
const struct dirent *ent;
|
||||||
|
DIR *dir;
|
||||||
|
int save, rc;
|
||||||
|
|
||||||
|
if (!cb || !name) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
save = errno;
|
||||||
|
|
||||||
|
cb_dirfd = openat(dirfd, name, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
|
||||||
|
if (cb_dirfd == -1) {
|
||||||
|
PDEBUG("could not open directory fd '%d' '%s': %m\n", dirfd, name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dir = fdopendir(cb_dirfd);
|
||||||
|
if (!dir) {
|
||||||
|
PDEBUG("could not open directory '%s' from fd '%d': %m\n", name, cb_dirfd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* dup cd_dirfd because fdopendir has claimed the fd passed to it */
|
||||||
|
cb_dirfd = dup(cb_dirfd);
|
||||||
|
if (!dir) {
|
||||||
|
PDEBUG("could not dup directory fd '%s': %m\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((ent = readdir(dir))) {
|
||||||
|
if (cb) {
|
||||||
|
rc = (*cb)(cb_dirfd, ent, data);
|
||||||
|
if (rc) {
|
||||||
|
PDEBUG("dir_for_each callback failed for '%s'\n",
|
||||||
|
ent->d_name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errno = save;
|
||||||
|
|
||||||
|
out:
|
||||||
|
closedir(dir);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define max(a, b) \
|
||||||
|
({ __typeof__ (a) _a = (a); \
|
||||||
|
__typeof__ (b) _b = (b); \
|
||||||
|
_a > _b ? _a : _b; })
|
||||||
|
#define CHUNK 32
|
||||||
|
struct overlaydir {
|
||||||
|
int dirfd;
|
||||||
|
struct dirent *dent;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int insert(struct overlaydir **overlayptr, int *max_size, int *size,
|
||||||
|
int pos, int remaining, int dirfd, struct dirent *ent)
|
||||||
|
{
|
||||||
|
struct overlaydir *overlay = *overlayptr;
|
||||||
|
int i, chunk = max(remaining, CHUNK);
|
||||||
|
|
||||||
|
if (size + 1 >= max_size) {
|
||||||
|
struct overlaydir *tmp = reallocarray(overlay,
|
||||||
|
*max_size + chunk,
|
||||||
|
sizeof(*overlay));
|
||||||
|
if (tmp == NULL)
|
||||||
|
return -1;
|
||||||
|
overlay = tmp;
|
||||||
|
}
|
||||||
|
*max_size += chunk;
|
||||||
|
(*size)++;
|
||||||
|
for (i = *size; i > pos; i--)
|
||||||
|
overlay[i] = overlay[i - 1];
|
||||||
|
overlay[pos].dirfd = dirfd;
|
||||||
|
overlay[pos].dent = ent;
|
||||||
|
|
||||||
|
*overlayptr = overlay;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define merge(overlay, n_overlay, max_size, list, n_list, dirfd) \
|
||||||
|
({ \
|
||||||
|
int i, j; \
|
||||||
|
int rc = 0; \
|
||||||
|
\
|
||||||
|
for (i = 0, j = 0; i < n_overlay && j < n_list; ) { \
|
||||||
|
int res = strcmp(overlay[i].dent->d_name, list[j]->d_name);\
|
||||||
|
if (res < 0) { \
|
||||||
|
i++; \
|
||||||
|
continue; \
|
||||||
|
} else if (res == 0) { \
|
||||||
|
free(list[j]); \
|
||||||
|
list[j] = NULL; \
|
||||||
|
i++; \
|
||||||
|
j++; \
|
||||||
|
} else { \
|
||||||
|
if ((rc = insert(&overlay, &max_size, &n_overlay, i,\
|
||||||
|
n_list - j, dirfd, list[j]))) \
|
||||||
|
goto fail; \
|
||||||
|
i++; \
|
||||||
|
list[j++] = NULL; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (j < n_list) { \
|
||||||
|
if ((rc = insert(&overlay, &max_size, &n_overlay, i, \
|
||||||
|
n_list - j, dirfd,list[j]))) \
|
||||||
|
goto fail; \
|
||||||
|
i++; \
|
||||||
|
list[j++] = NULL; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
fail: \
|
||||||
|
rc; \
|
||||||
|
})
|
||||||
|
|
||||||
|
int _aa_overlaydirat_for_each(int dirfd[], int n, void *data,
|
||||||
|
int (* cb)(int, const char *, struct stat *, void *))
|
||||||
|
{
|
||||||
|
autofree struct dirent **list = NULL;
|
||||||
|
autofree struct overlaydir *overlay = NULL;
|
||||||
|
int i, k;
|
||||||
|
int n_list, size = 0, max_size = 0;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
n_list = scandirat(dirfd[i], ".", &list, dot_or_dot_dot_filter,
|
||||||
|
alphasort);
|
||||||
|
if (n_list == -1) {
|
||||||
|
PDEBUG("scandirat of dirfd[%d] failed: %m\n", i);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (merge(overlay, size, max_size, list, n_list, dirfd[i])) {
|
||||||
|
for (k = 0; k < n_list; k++)
|
||||||
|
free(list[i]);
|
||||||
|
for (k = 0; k < size; k++)
|
||||||
|
free(overlay[k].dent);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (rc = 0, i = 0; i < size; i++) {
|
||||||
|
/* Must cycle through all dirs so that each one is autofreed */
|
||||||
|
autofree struct dirent *dent = overlay[i].dent;
|
||||||
|
struct stat my_stat;
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (fstatat(overlay[i].dirfd, dent->d_name, &my_stat,
|
||||||
|
AT_SYMLINK_NOFOLLOW)) {
|
||||||
|
PDEBUG("stat failed for '%s': %m\n", dent->d_name);
|
||||||
|
rc = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cb(overlay[i].dirfd, dent->d_name, &my_stat, data)) {
|
||||||
|
PDEBUG("dir_for_each callback failed for '%s'\n",
|
||||||
|
dent->d_name);
|
||||||
|
rc = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _aa_dirat_for_each: iterate over a directory calling cb for each entry
|
* _aa_dirat_for_each: iterate over a directory calling cb for each entry
|
||||||
* @dirfd: already opened directory
|
* @dirfd: already opened directory
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#ifndef _AA_PRIVATE_H
|
#ifndef _AA_PRIVATE_H
|
||||||
#define _AA_PRIVATE_H 1
|
#define _AA_PRIVATE_H 1
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <sys/apparmor_private.h>
|
#include <sys/apparmor_private.h>
|
||||||
|
|
||||||
@@ -51,4 +52,7 @@ void print_debug(const char *fmt, ...);
|
|||||||
void atomic_inc(unsigned int *v);
|
void atomic_inc(unsigned int *v);
|
||||||
bool atomic_dec_and_test(unsigned int *v);
|
bool atomic_dec_and_test(unsigned int *v);
|
||||||
|
|
||||||
|
int _aa_dirat_for_each2(int dirfd, const char *name, void *data,
|
||||||
|
int (* cb)(int, const struct dirent *, void *));
|
||||||
|
|
||||||
#endif /* _AA_PRIVATE_H */
|
#endif /* _AA_PRIVATE_H */
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
# Copyright (c) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
|
# Copyright (c) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
|
||||||
# NOVELL (All rights reserved)
|
# NOVELL (All rights reserved)
|
||||||
#
|
#
|
||||||
|
# Copyright (c) Christian Boltz 2018
|
||||||
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of version 2 of the GNU General Public
|
# modify it under the terms of version 2 of the GNU General Public
|
||||||
# License published by the Free Software Foundation.
|
# License published by the Free Software Foundation.
|
||||||
@@ -22,10 +24,11 @@ include $(COMMONDIR)/Make.rules
|
|||||||
|
|
||||||
DESTDIR=/
|
DESTDIR=/
|
||||||
APPARMOR_BIN_PREFIX=${DESTDIR}/lib/apparmor
|
APPARMOR_BIN_PREFIX=${DESTDIR}/lib/apparmor
|
||||||
|
SYSTEMD_UNIT_DIR=${DESTDIR}/usr/lib/systemd/system
|
||||||
CONFDIR=/etc/apparmor
|
CONFDIR=/etc/apparmor
|
||||||
INSTALL_CONFDIR=${DESTDIR}${CONFDIR}
|
INSTALL_CONFDIR=${DESTDIR}${CONFDIR}
|
||||||
LOCALEDIR=/usr/share/locale
|
LOCALEDIR=/usr/share/locale
|
||||||
MANPAGES=apparmor.d.5 apparmor.7 apparmor_parser.8 subdomain.conf.5
|
MANPAGES=apparmor.d.5 apparmor.7 apparmor_parser.8 subdomain.conf.5 aa-teardown.8
|
||||||
|
|
||||||
YACC := /usr/bin/bison
|
YACC := /usr/bin/bison
|
||||||
YFLAGS := -d
|
YFLAGS := -d
|
||||||
@@ -314,12 +317,9 @@ install-redhat:
|
|||||||
install -m 755 rc.apparmor.$(subst install-,,$@) $(DESTDIR)/etc/init.d/apparmor
|
install -m 755 rc.apparmor.$(subst install-,,$@) $(DESTDIR)/etc/init.d/apparmor
|
||||||
|
|
||||||
.PHONY: install-suse
|
.PHONY: install-suse
|
||||||
install-suse:
|
install-suse: install-systemd
|
||||||
install -m 755 -d $(DESTDIR)/etc/init.d
|
|
||||||
install -m 755 rc.apparmor.$(subst install-,,$(@)) $(DESTDIR)/etc/init.d/boot.apparmor
|
|
||||||
install -m 755 -d $(DESTDIR)/sbin
|
install -m 755 -d $(DESTDIR)/sbin
|
||||||
ln -sf /etc/init.d/boot.apparmor $(DESTDIR)/sbin/rcapparmor
|
ln -sf service $(DESTDIR)/sbin/rcapparmor
|
||||||
ln -sf rcapparmor $(DESTDIR)/sbin/rcsubdomain
|
|
||||||
|
|
||||||
.PHONY: install-slackware
|
.PHONY: install-slackware
|
||||||
install-slackware:
|
install-slackware:
|
||||||
@@ -379,6 +379,14 @@ install-indep: indep
|
|||||||
$(MAKE) -C po install NAME=${NAME} DESTDIR=${DESTDIR}
|
$(MAKE) -C po install NAME=${NAME} DESTDIR=${DESTDIR}
|
||||||
$(MAKE) install_manpages DESTDIR=${DESTDIR}
|
$(MAKE) install_manpages DESTDIR=${DESTDIR}
|
||||||
|
|
||||||
|
.PHONY: install-systemd
|
||||||
|
install-systemd:
|
||||||
|
install -m 755 -d $(SYSTEMD_UNIT_DIR)
|
||||||
|
install -m 644 apparmor.service $(SYSTEMD_UNIT_DIR)
|
||||||
|
install -m 644 apparmor.systemd $(APPARMOR_BIN_PREFIX)
|
||||||
|
install -m 755 -d $(DESTDIR)/sbin
|
||||||
|
install -m 755 aa-teardown $(DESTDIR)/sbin
|
||||||
|
|
||||||
ifndef VERBOSE
|
ifndef VERBOSE
|
||||||
.SILENT: clean
|
.SILENT: clean
|
||||||
endif
|
endif
|
||||||
|
10
parser/aa-teardown
Normal file
10
parser/aa-teardown
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
test $# = 0 || {
|
||||||
|
echo "Usage: $0"
|
||||||
|
echo
|
||||||
|
echo "Unloads all AppArmor profiles"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/lib/apparmor/apparmor.systemd stop
|
40
parser/aa-teardown.pod
Normal file
40
parser/aa-teardown.pod
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Copyright (c) 2018 Christian Boltz
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of version 2 of the GNU General Public
|
||||||
|
# License 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, contact Novell, Inc.
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
aa-teardown - unload all AppArmor profiles
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
B<aa-teardown>
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
aa-teardown unloads all AppArmor profiles
|
||||||
|
|
||||||
|
=head1 BUGS
|
||||||
|
|
||||||
|
If you find any bugs, please report them at
|
||||||
|
L<https://bugs.launchpad.net/apparmor/+filebug>.
|
||||||
|
|
||||||
|
=head1 SEE ALSO
|
||||||
|
|
||||||
|
apparmor(7), apparmor.d(5), and L<http://wiki.apparmor.net>.
|
||||||
|
|
||||||
|
=cut
|
@@ -55,7 +55,7 @@ B<VARIABLE> = '@{' I<ALPHA> [ ( I<ALPHANUMERIC> | '_' ) ... ] '}'
|
|||||||
|
|
||||||
B<ALIAS RULE> = 'alias' I<ABS PATH> '-E<gt>' I<REWRITTEN ABS PATH> ','
|
B<ALIAS RULE> = 'alias' I<ABS PATH> '-E<gt>' I<REWRITTEN ABS PATH> ','
|
||||||
|
|
||||||
B<INCLUDE> = '#include' ( I<ABS PATH> | I<MAGIC PATH> )
|
B<INCLUDE> = ( '#include' | 'include' ) [ 'if exists' ] ( I<ABS PATH> | I<MAGIC PATH> )
|
||||||
|
|
||||||
B<ABS PATH> = '"' path '"' (the path is passed to open(2))
|
B<ABS PATH> = '"' path '"' (the path is passed to open(2))
|
||||||
|
|
||||||
@@ -1414,13 +1414,17 @@ rules into a rule block.
|
|||||||
|
|
||||||
=head2 #include mechanism
|
=head2 #include mechanism
|
||||||
|
|
||||||
AppArmor provides an easy abstraction mechanism to group common file
|
AppArmor provides an easy abstraction mechanism to group common
|
||||||
access requirements; this abstraction is an extremely flexible way to
|
access requirements; this abstraction is an extremely flexible way to
|
||||||
grant site-specific rights and makes writing new AppArmor profiles very
|
grant site-specific rights and makes writing new AppArmor profiles very
|
||||||
simple by assembling the needed building blocks for any given program.
|
simple by assembling the needed building blocks for any given program.
|
||||||
|
|
||||||
The use of '#include' is modelled directly after cpp(1); its use will
|
The use of '#include' is modelled directly after cpp(1); its use will
|
||||||
replace the '#include' statement with the specified file's contents.
|
replace the '#include' statement with the specified file's contents.
|
||||||
|
The leading '#' is optional, and the '#include' keyword can be followed
|
||||||
|
by an option conditional 'if exists' that specifies profile compilation
|
||||||
|
should continue if the specified file or directory is not found.
|
||||||
|
|
||||||
B<#include "/absolute/path"> specifies that F</absolute/path> should be
|
B<#include "/absolute/path"> specifies that F</absolute/path> should be
|
||||||
used. B<#include "relative/path"> specifies that F<relative/path> should
|
used. B<#include "relative/path"> specifies that F<relative/path> should
|
||||||
be used, where the path is relative to the current working directory.
|
be used, where the path is relative to the current working directory.
|
||||||
|
@@ -70,9 +70,12 @@ with B<.> (except for the root B</>) so profiles are easier to manage
|
|||||||
(e.g. the F</usr/sbin/nscd> profile would be named F<usr.sbin.nscd>).
|
(e.g. the F</usr/sbin/nscd> profile would be named F<usr.sbin.nscd>).
|
||||||
|
|
||||||
Profiles are applied to a process at exec(3) time (as seen through the
|
Profiles are applied to a process at exec(3) time (as seen through the
|
||||||
execve(2) system call); an already running process cannot be confined.
|
execve(2) system call): once a profile is loaded for a program, that
|
||||||
However, once a profile is loaded for a program, that program will be
|
program will be confined on the next exec(3). If a process is already
|
||||||
confined on the next exec(3).
|
running under a profile, when one replaces that profile in the kernel,
|
||||||
|
the updated profile is applied immediately to that process.
|
||||||
|
On the other hand, a process that is already running unconfined cannot
|
||||||
|
be confined.
|
||||||
|
|
||||||
AppArmor supports the Linux kernel's securityfs filesystem, and makes
|
AppArmor supports the Linux kernel's securityfs filesystem, and makes
|
||||||
available the list of the profiles currently loaded; to mount the
|
available the list of the profiles currently loaded; to mount the
|
||||||
|
26
parser/apparmor.service
Normal file
26
parser/apparmor.service
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Load AppArmor profiles
|
||||||
|
DefaultDependencies=no
|
||||||
|
Before=sysinit.target
|
||||||
|
After=systemd-journald-audit.socket
|
||||||
|
# profile cache
|
||||||
|
After=var.mount var-lib.mount
|
||||||
|
ConditionSecurity=apparmor
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/lib/apparmor/apparmor.systemd reload
|
||||||
|
ExecReload=/lib/apparmor/apparmor.systemd reload
|
||||||
|
|
||||||
|
# systemd maps 'restart' to 'stop; start' which means removing AppArmor confinement
|
||||||
|
# from running processes (and not being able to re-apply it later).
|
||||||
|
# Upstream systemd developers refused to implement an option that allows overriding
|
||||||
|
# this behaviour, therefore we have to make ExecStop a no-op to error out on the
|
||||||
|
# safe side.
|
||||||
|
#
|
||||||
|
# If you really want to unload all AppArmor profiles, run aa-teardown
|
||||||
|
ExecStop=/bin/true
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
100
parser/apparmor.systemd
Normal file
100
parser/apparmor.systemd
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of version 2 of the GNU General Public
|
||||||
|
# License 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, contact Novell, Inc.
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions
|
||||||
|
|
||||||
|
aa_action()
|
||||||
|
{
|
||||||
|
echo $1
|
||||||
|
shift
|
||||||
|
"$@"
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
aa_log_warning_msg()
|
||||||
|
{
|
||||||
|
echo "Warning: $@"
|
||||||
|
}
|
||||||
|
|
||||||
|
aa_log_failure_msg()
|
||||||
|
{
|
||||||
|
echo "Error: $@"
|
||||||
|
}
|
||||||
|
|
||||||
|
aa_log_action_start()
|
||||||
|
{
|
||||||
|
echo "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
aa_log_action_end()
|
||||||
|
{
|
||||||
|
echo -n
|
||||||
|
}
|
||||||
|
|
||||||
|
aa_log_daemon_msg()
|
||||||
|
{
|
||||||
|
echo "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
aa_log_skipped_msg()
|
||||||
|
{
|
||||||
|
echo "Skipped: $@"
|
||||||
|
}
|
||||||
|
|
||||||
|
aa_log_end_msg()
|
||||||
|
{
|
||||||
|
echo -n
|
||||||
|
}
|
||||||
|
|
||||||
|
# source apparmor function library
|
||||||
|
if [ -f "${APPARMOR_FUNCTIONS}" ]; then
|
||||||
|
. ${APPARMOR_FUNCTIONS}
|
||||||
|
else
|
||||||
|
aa_log_failure_msg "Unable to find AppArmor initscript functions"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
apparmor_start
|
||||||
|
rc=$?
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
apparmor_stop
|
||||||
|
rc=$?
|
||||||
|
;;
|
||||||
|
restart|reload|force-reload)
|
||||||
|
apparmor_restart
|
||||||
|
rc=$?
|
||||||
|
;;
|
||||||
|
try-restart)
|
||||||
|
apparmor_try_restart
|
||||||
|
rc=$?
|
||||||
|
;;
|
||||||
|
kill)
|
||||||
|
apparmor_kill
|
||||||
|
rc=$?
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
apparmor_status
|
||||||
|
rc=$?
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
exit $rc
|
@@ -46,9 +46,10 @@ program. The B<profiles> may be specified by file name or a directory
|
|||||||
name containing a set of profiles. If a directory is specified then the
|
name containing a set of profiles. If a directory is specified then the
|
||||||
B<apparmor_parser> will try to do a profile load for each file in the
|
B<apparmor_parser> will try to do a profile load for each file in the
|
||||||
directory that is not a dot file, or explicitly black listed (*.dpkg-new,
|
directory that is not a dot file, or explicitly black listed (*.dpkg-new,
|
||||||
*.dpkg-old, *.dpkg-dist, *-dpkg-bak, *.repnew, *.rpmsave, *orig, *.rej,
|
*.dpkg-old, *.dpkg-dist, *.dpkg-bak, *.dpkg-remove, *.pacsave, *.pacnew,
|
||||||
*~). The B<apparmor_parser> will fall back to taking input from standard
|
*.rpmnew, *.rpmsave, *.orig, *.rej, *~).
|
||||||
input if a profile or directory is not supplied.
|
The B<apparmor_parser> will fall back to taking input from standard input if
|
||||||
|
a profile or directory is not supplied.
|
||||||
|
|
||||||
The input supplied to B<apparmor_parser> should be in the format described in
|
The input supplied to B<apparmor_parser> should be in the format described in
|
||||||
apparmor.d(5).
|
apparmor.d(5).
|
||||||
@@ -232,8 +233,28 @@ inconsistent state
|
|||||||
|
|
||||||
=item -L, --cache-loc
|
=item -L, --cache-loc
|
||||||
|
|
||||||
Set the location of the cache directory. If not specified the cache location
|
Set the location(s) of the cache directory. This option can accept a
|
||||||
defaults to /etc/apparmor.d/cache
|
comma separated list of directories, which will be searched in order
|
||||||
|
to find a matching cache. The first matching cache file found is used
|
||||||
|
even if a directory later in the search order may contain a newer cache
|
||||||
|
file.
|
||||||
|
|
||||||
|
If multiple directories are specified and --write-cache has been specified
|
||||||
|
then cache writes will be made to the first directory in the list, all
|
||||||
|
other directories will be treated as read only.
|
||||||
|
|
||||||
|
If a cache directory name needs to have a comma as part of the name, it
|
||||||
|
can be specified by using a backslash to escape the comma character in
|
||||||
|
the directory name.
|
||||||
|
|
||||||
|
If not specified the cache location defaults to /etc/apparmor.d/cache.d
|
||||||
|
|
||||||
|
=item --print-cache-dir
|
||||||
|
|
||||||
|
Print the cache directory location. This path will be a subdirectory of the
|
||||||
|
directory specified by --cache-loc. The subdirectory used will be influenced by
|
||||||
|
the features available in the currently running kernel or by the features
|
||||||
|
specified with the --match-string or --features-file options.
|
||||||
|
|
||||||
=item -Q, --skip-kernel-load
|
=item -Q, --skip-kernel-load
|
||||||
|
|
||||||
|
@@ -144,7 +144,7 @@ static int include_dir_cb(int dirfd unused, const char *name, struct stat *st,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void include_filename(char *filename, int search)
|
void include_filename(char *filename, int search, bool if_exists)
|
||||||
{
|
{
|
||||||
FILE *include_file = NULL;
|
FILE *include_file = NULL;
|
||||||
struct stat my_stat;
|
struct stat my_stat;
|
||||||
@@ -161,11 +161,14 @@ void include_filename(char *filename, int search)
|
|||||||
include_file = fopen(fullpath, "r");
|
include_file = fopen(fullpath, "r");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!include_file)
|
if (!include_file) {
|
||||||
|
if (if_exists)
|
||||||
|
return;
|
||||||
yyerror(_("Could not open '%s'"),
|
yyerror(_("Could not open '%s'"),
|
||||||
fullpath ? fullpath: filename);
|
fullpath ? fullpath: filename);
|
||||||
|
}
|
||||||
|
|
||||||
if (fstat(fileno(include_file), &my_stat))
|
if (fstat(fileno(include_file), &my_stat))
|
||||||
yyerror(_("fstat failed for '%s'"), fullpath);
|
yyerror(_("fstat failed for '%s'"), fullpath);
|
||||||
|
|
||||||
if (S_ISREG(my_stat.st_mode)) {
|
if (S_ISREG(my_stat.st_mode)) {
|
||||||
@@ -200,7 +203,7 @@ MODES {MODE_CHARS}+
|
|||||||
WS [[:blank:]]
|
WS [[:blank:]]
|
||||||
NUMBER [[:digit:]]+
|
NUMBER [[:digit:]]+
|
||||||
|
|
||||||
ID_CHARS [^ \t\n"!,]
|
ID_CHARS [^ \t\r\n"!,]
|
||||||
ID {ID_CHARS}|(,{ID_CHARS}|\\[ ]|\\\t|\\\"|\\!|\\,)
|
ID {ID_CHARS}|(,{ID_CHARS}|\\[ ]|\\\t|\\\"|\\!|\\,)
|
||||||
IDS {ID}+
|
IDS {ID}+
|
||||||
POST_VAR_ID_CHARS [^ \t\n"!,]{-}[=\+]
|
POST_VAR_ID_CHARS [^ \t\n"!,]{-}[=\+]
|
||||||
@@ -257,6 +260,7 @@ LT_EQUAL <=
|
|||||||
%x UNIX_MODE
|
%x UNIX_MODE
|
||||||
%x CHANGE_PROFILE_MODE
|
%x CHANGE_PROFILE_MODE
|
||||||
%x INCLUDE
|
%x INCLUDE
|
||||||
|
%x INCLUDE_EXISTS
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
@@ -269,19 +273,44 @@ LT_EQUAL <=
|
|||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
<INITIAL,SUB_ID_WS,INCLUDE,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE>{
|
<INITIAL,SUB_ID_WS,INCLUDE,INCLUDE_EXISTS,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE>{
|
||||||
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
|
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
<INCLUDE>{
|
<INCLUDE_EXISTS>{
|
||||||
(\<([^\> \t\n]+)\>|\"([^\" \t\n]+)\") { /* <filename> */
|
(\<([^"\>\t\r\n]+)\>|{QUOTED_ID}) { /* <filename> | "filename" */
|
||||||
autofree char *filename = strndup(yytext, yyleng - 1);
|
autofree char *filename = strndup(yytext, yyleng - 1);
|
||||||
include_filename(filename + 1, *filename == '<');
|
include_filename(filename + 1, *filename == '<', true);
|
||||||
POP_NODUMP();
|
POP_NODUMP();
|
||||||
}
|
}
|
||||||
|
|
||||||
[^\<\>\" \t\n]+ { /* filename */
|
(\<{QUOTED_ID}\>) { /* <"filename"> */
|
||||||
include_filename(yytext, 0);
|
autofree char *filename = strndup(yytext, yyleng - 2);
|
||||||
|
include_filename(filename + 2, true, true);
|
||||||
|
POP_NODUMP();
|
||||||
|
}
|
||||||
|
|
||||||
|
({IDS}|{QUOTED_ID}) { /* filename */
|
||||||
|
include_filename(yytext, 0, true);
|
||||||
|
POP_NODUMP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<INCLUDE>{
|
||||||
|
(\<([^"\>\t\r\n]+)\>|{QUOTED_ID}) { /* <filename> | "filename" */
|
||||||
|
autofree char *filename = strndup(yytext, yyleng - 1);
|
||||||
|
include_filename(filename + 1, *filename == '<', false);
|
||||||
|
POP_NODUMP();
|
||||||
|
}
|
||||||
|
|
||||||
|
(\<{QUOTED_ID}\>) { /* <"filename"> */
|
||||||
|
autofree char *filename = strndup(yytext, yyleng - 2);
|
||||||
|
include_filename(filename + 2, true, false);
|
||||||
|
POP_NODUMP();
|
||||||
|
}
|
||||||
|
|
||||||
|
({IDS}|{QUOTED_ID}) { /* filename */
|
||||||
|
include_filename(yytext, 0, false);
|
||||||
POP_NODUMP();
|
POP_NODUMP();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -527,6 +556,20 @@ LT_EQUAL <=
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include{WS}+if{WS}+exists/{WS}.*\r?\n {
|
||||||
|
/* Don't use PUSH() macro here as we don't want #include echoed out.
|
||||||
|
* It needs to be handled specially
|
||||||
|
*/
|
||||||
|
yy_push_state(INCLUDE_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
include{WS}+if{WS}+exists/{WS} {
|
||||||
|
/* Don't use PUSH() macro here as we don't want #include echoed out.
|
||||||
|
* It needs to be handled specially
|
||||||
|
*/
|
||||||
|
yy_push_state(INCLUDE_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
#include/.*\r?\n {
|
#include/.*\r?\n {
|
||||||
/* Don't use PUSH() macro here as we don't want #include echoed out.
|
/* Don't use PUSH() macro here as we don't want #include echoed out.
|
||||||
* It needs to be handled specially
|
* It needs to be handled specially
|
||||||
@@ -675,4 +718,5 @@ unordered_map<int, string> state_names = {
|
|||||||
STATE_TABLE_ENT(UNIX_MODE),
|
STATE_TABLE_ENT(UNIX_MODE),
|
||||||
STATE_TABLE_ENT(CHANGE_PROFILE_MODE),
|
STATE_TABLE_ENT(CHANGE_PROFILE_MODE),
|
||||||
STATE_TABLE_ENT(INCLUDE),
|
STATE_TABLE_ENT(INCLUDE),
|
||||||
|
STATE_TABLE_ENT(INCLUDE_EXISTS),
|
||||||
};
|
};
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
||||||
* NOVELL (All rights reserved)
|
* NOVELL (All rights reserved)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2010 - 2013
|
* Copyright (c) 2010 - 2018
|
||||||
* Canonical Ltd. (All rights reserved)
|
* Canonical Ltd. (All rights reserved)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
#define UNPRIVILEGED_OPS (!(PRIVILEGED_OPS))
|
#define UNPRIVILEGED_OPS (!(PRIVILEGED_OPS))
|
||||||
|
|
||||||
const char *parser_title = "AppArmor parser";
|
const char *parser_title = "AppArmor parser";
|
||||||
const char *parser_copyright = "Copyright (C) 1999-2008 Novell Inc.\nCopyright 2009-2012 Canonical Ltd.";
|
const char *parser_copyright = "Copyright (C) 1999-2008 Novell Inc.\nCopyright 2009-2018 Canonical Ltd.";
|
||||||
|
|
||||||
int opt_force_complain = 0;
|
int opt_force_complain = 0;
|
||||||
int binary_input = 0;
|
int binary_input = 0;
|
||||||
@@ -97,12 +97,17 @@ long jobs_scale = 0; /* number of chance to resample online
|
|||||||
*/
|
*/
|
||||||
bool debug_jobs = false;
|
bool debug_jobs = false;
|
||||||
|
|
||||||
|
#define MAX_CACHE_LOCS 4
|
||||||
|
|
||||||
struct timespec cache_tstamp, mru_policy_tstamp;
|
struct timespec cache_tstamp, mru_policy_tstamp;
|
||||||
|
|
||||||
static char *apparmorfs = NULL;
|
static char *apparmorfs = NULL;
|
||||||
static char *cacheloc = NULL;
|
static char *cacheloc[MAX_CACHE_LOCS];
|
||||||
|
static int cacheloc_n = 0;
|
||||||
|
static bool print_cache_dir = false;
|
||||||
|
|
||||||
static aa_features *features = NULL;
|
static aa_features *compile_features = NULL;
|
||||||
|
static aa_features *kernel_features = NULL;
|
||||||
|
|
||||||
/* Make sure to update BOTH the short and long_options */
|
/* Make sure to update BOTH the short and long_options */
|
||||||
static const char *short_options = "ad::f:h::rRVvI:b:BCD:NSm:M:qQn:XKTWkL:O:po:j:";
|
static const char *short_options = "ad::f:h::rRVvI:b:BCD:NSm:M:qQn:XKTWkL:O:po:j:";
|
||||||
@@ -124,6 +129,7 @@ struct option long_options[] = {
|
|||||||
{"ofile", 1, 0, 'o'},
|
{"ofile", 1, 0, 'o'},
|
||||||
{"match-string", 1, 0, 'm'},
|
{"match-string", 1, 0, 'm'},
|
||||||
{"features-file", 1, 0, 'M'},
|
{"features-file", 1, 0, 'M'},
|
||||||
|
{"kernel-features", 1, 0, 138}, /* no short option */
|
||||||
{"quiet", 0, 0, 'q'},
|
{"quiet", 0, 0, 'q'},
|
||||||
{"skip-kernel-load", 0, 0, 'Q'},
|
{"skip-kernel-load", 0, 0, 'Q'},
|
||||||
{"verbose", 0, 0, 'v'},
|
{"verbose", 0, 0, 'v'},
|
||||||
@@ -149,6 +155,7 @@ struct option long_options[] = {
|
|||||||
{"debug-cache", 0, 0, 135}, /* no short option */
|
{"debug-cache", 0, 0, 135}, /* no short option */
|
||||||
{"jobs", 1, 0, 'j'},
|
{"jobs", 1, 0, 'j'},
|
||||||
{"max-jobs", 1, 0, 136}, /* no short option */
|
{"max-jobs", 1, 0, 136}, /* no short option */
|
||||||
|
{"print-cache-dir", 0, 0, 137}, /* no short option */
|
||||||
{NULL, 0, 0, 0},
|
{NULL, 0, 0, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,7 +185,8 @@ static void display_usage(const char *command)
|
|||||||
"-I n, --Include n Add n to the search path\n"
|
"-I n, --Include n Add n to the search path\n"
|
||||||
"-f n, --subdomainfs n Set location of apparmor filesystem\n"
|
"-f n, --subdomainfs n Set location of apparmor filesystem\n"
|
||||||
"-m n, --match-string n Use only features n\n"
|
"-m n, --match-string n Use only features n\n"
|
||||||
"-M n, --features-file n Use only features in file n\n"
|
"-M n, --features-file n Compile features set in file n\n"
|
||||||
|
"--kernel-features n Kernel features set in file n\n"
|
||||||
"-n n, --namespace n Set Namespace for the profile\n"
|
"-n n, --namespace n Set Namespace for the profile\n"
|
||||||
"-X, --readimpliesX Map profile read permissions to mr\n"
|
"-X, --readimpliesX Map profile read permissions to mr\n"
|
||||||
"-k, --show-cache Report cache hit/miss details\n"
|
"-k, --show-cache Report cache hit/miss details\n"
|
||||||
@@ -188,7 +196,8 @@ static void display_usage(const char *command)
|
|||||||
" --skip-bad-cache Don't clear cache if out of sync\n"
|
" --skip-bad-cache Don't clear cache if out of sync\n"
|
||||||
" --purge-cache Clear cache regardless of its state\n"
|
" --purge-cache Clear cache regardless of its state\n"
|
||||||
" --debug-cache Debug cache file checks\n"
|
" --debug-cache Debug cache file checks\n"
|
||||||
"-L, --cache-loc n Set the location of the profile cache\n"
|
" --print-cache_dir Print the cache directory path\n"
|
||||||
|
"-L, --cache-loc n Set the location of the profile caches\n"
|
||||||
"-q, --quiet Don't emit warnings\n"
|
"-q, --quiet Don't emit warnings\n"
|
||||||
"-v, --verbose Show profile names as they load\n"
|
"-v, --verbose Show profile names as they load\n"
|
||||||
"-Q, --skip-kernel-load Do everything except loading into kernel\n"
|
"-Q, --skip-kernel-load Do everything except loading into kernel\n"
|
||||||
@@ -222,6 +231,51 @@ void display_warn(const char *command)
|
|||||||
print_flag_table(warnflag_table);
|
print_flag_table(warnflag_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse comma separated cachelocations. Commas can be escaped by \, */
|
||||||
|
static int parse_cacheloc(const char *arg, char **cacheloc, int max_size)
|
||||||
|
{
|
||||||
|
const char *s = arg;
|
||||||
|
const char *p = arg;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
while(*p) {
|
||||||
|
if (*p == '\\') {
|
||||||
|
if (*(p + 1) != 0)
|
||||||
|
p++;
|
||||||
|
} else if (*p == ',') {
|
||||||
|
if (p != s) {
|
||||||
|
if (n == max_size) {
|
||||||
|
errno = E2BIG;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cacheloc[n] = (char *) malloc(p - s + 1);
|
||||||
|
if (cacheloc[n] == NULL)
|
||||||
|
return -1;
|
||||||
|
memcpy(cacheloc[n], s, p - s);
|
||||||
|
cacheloc[n][p - s] = 0;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
s = p;
|
||||||
|
} else
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if (p != s) {
|
||||||
|
if (n == max_size) {
|
||||||
|
errno = E2BIG;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cacheloc[n] = (char *) malloc(p - s + 1);
|
||||||
|
if (cacheloc[n] == NULL)
|
||||||
|
return -1;
|
||||||
|
memcpy(cacheloc[n], s, p - s);
|
||||||
|
cacheloc[n][p - s] = 0;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
/* Treat conf file like options passed on command line
|
/* Treat conf file like options passed on command line
|
||||||
*/
|
*/
|
||||||
static int getopt_long_file(FILE *f, const struct option *longopts,
|
static int getopt_long_file(FILE *f, const struct option *longopts,
|
||||||
@@ -329,8 +383,7 @@ static int process_arg(int c, char *optarg)
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case 0:
|
case 0:
|
||||||
PERROR("Assert, in getopt_long handling\n");
|
PERROR("Assert, in getopt_long handling\n");
|
||||||
display_usage(progname);
|
exit(1);
|
||||||
exit(0);
|
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
count++;
|
count++;
|
||||||
@@ -449,7 +502,7 @@ static int process_arg(int c, char *optarg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (aa_features_new_from_string(&features,
|
if (aa_features_new_from_string(&compile_features,
|
||||||
optarg, strlen(optarg))) {
|
optarg, strlen(optarg))) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Failed to parse features string: %m\n");
|
"Failed to parse features string: %m\n");
|
||||||
@@ -457,13 +510,21 @@ static int process_arg(int c, char *optarg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
if (aa_features_new(&features, AT_FDCWD, optarg)) {
|
if (aa_features_new(&compile_features, AT_FDCWD, optarg)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Failed to load features from '%s': %m\n",
|
"Failed to load features from '%s': %m\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 138:
|
||||||
|
if (aa_features_new(&kernel_features, AT_FDCWD, optarg)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Failed to load kernel features from '%s': %m\n",
|
||||||
|
optarg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
conf_verbose = 0;
|
conf_verbose = 0;
|
||||||
conf_quiet = 1;
|
conf_quiet = 1;
|
||||||
@@ -507,7 +568,11 @@ static int process_arg(int c, char *optarg)
|
|||||||
skip_bad_cache_rebuild = 1;
|
skip_bad_cache_rebuild = 1;
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
cacheloc = strdup(optarg);
|
cacheloc_n = parse_cacheloc(optarg, cacheloc, MAX_CACHE_LOCS);
|
||||||
|
if (cacheloc_n == -1) {
|
||||||
|
PERROR("%s: Invalid --cacheloc option '%s' %m\n", progname, optarg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'Q':
|
case 'Q':
|
||||||
kernel_load = 0;
|
kernel_load = 0;
|
||||||
@@ -536,8 +601,12 @@ static int process_arg(int c, char *optarg)
|
|||||||
case 136:
|
case 136:
|
||||||
jobs_max = process_jobs_arg("max-jobs", optarg);
|
jobs_max = process_jobs_arg("max-jobs", optarg);
|
||||||
break;
|
break;
|
||||||
|
case 137:
|
||||||
|
kernel_load = 0;
|
||||||
|
print_cache_dir = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
display_usage(progname);
|
/* 'unrecognized option' error message gets printed by getopt_long() */
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -559,7 +628,6 @@ static int process_args(int argc, char *argv[])
|
|||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
PERROR("%s: Too many actions given on the command line.\n",
|
PERROR("%s: Too many actions given on the command line.\n",
|
||||||
progname);
|
progname);
|
||||||
display_usage(progname);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,7 +660,6 @@ int have_enough_privilege(void)
|
|||||||
if (uid != 0 && euid != 0) {
|
if (uid != 0 && euid != 0) {
|
||||||
PERROR(_("%s: Sorry. You need root privileges to run this program.\n\n"),
|
PERROR(_("%s: Sorry. You need root privileges to run this program.\n\n"),
|
||||||
progname);
|
progname);
|
||||||
display_usage(progname);
|
|
||||||
return EPERM;
|
return EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,33 +690,37 @@ no_match:
|
|||||||
perms_create = 1;
|
perms_create = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_supported_features(void)
|
static void set_supported_features(aa_features *kernel_features unused)
|
||||||
{
|
{
|
||||||
/* has process_args() already assigned a match string? */
|
/* has process_args() already assigned a match string? */
|
||||||
if (!features && aa_features_new_from_kernel(&features) == -1) {
|
if (!compile_features && aa_features_new_from_kernel(&compile_features) == -1) {
|
||||||
set_features_by_match_file();
|
set_features_by_match_file();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: intersect with actual kernel features to get proper
|
||||||
|
* rule down grades for a give kernel
|
||||||
|
*/
|
||||||
perms_create = 1;
|
perms_create = 1;
|
||||||
kernel_supports_policydb = aa_features_supports(features, "file");
|
kernel_supports_policydb = aa_features_supports(compile_features, "file");
|
||||||
kernel_supports_network = aa_features_supports(features, "network");
|
kernel_supports_network = aa_features_supports(compile_features, "network");
|
||||||
kernel_supports_unix = aa_features_supports(features,
|
kernel_supports_unix = aa_features_supports(compile_features,
|
||||||
"network/af_unix");
|
"network/af_unix");
|
||||||
kernel_supports_mount = aa_features_supports(features, "mount");
|
kernel_supports_mount = aa_features_supports(compile_features, "mount");
|
||||||
kernel_supports_dbus = aa_features_supports(features, "dbus");
|
kernel_supports_dbus = aa_features_supports(compile_features, "dbus");
|
||||||
kernel_supports_signal = aa_features_supports(features, "signal");
|
kernel_supports_signal = aa_features_supports(compile_features, "signal");
|
||||||
kernel_supports_ptrace = aa_features_supports(features, "ptrace");
|
kernel_supports_ptrace = aa_features_supports(compile_features, "ptrace");
|
||||||
kernel_supports_setload = aa_features_supports(features,
|
kernel_supports_setload = aa_features_supports(compile_features,
|
||||||
"policy/set_load");
|
"policy/set_load");
|
||||||
kernel_supports_diff_encode = aa_features_supports(features,
|
kernel_supports_diff_encode = aa_features_supports(compile_features,
|
||||||
"policy/diff_encode");
|
"policy/diff_encode");
|
||||||
kernel_supports_stacking = aa_features_supports(features,
|
kernel_supports_stacking = aa_features_supports(compile_features,
|
||||||
"domain/stack");
|
"domain/stack");
|
||||||
|
|
||||||
if (aa_features_supports(features, "policy/versions/v7"))
|
if (aa_features_supports(compile_features, "policy/versions/v7"))
|
||||||
kernel_abi_version = 7;
|
kernel_abi_version = 7;
|
||||||
else if (aa_features_supports(features, "policy/versions/v6"))
|
else if (aa_features_supports(compile_features, "policy/versions/v6"))
|
||||||
kernel_abi_version = 6;
|
kernel_abi_version = 6;
|
||||||
|
|
||||||
if (!kernel_supports_diff_encode)
|
if (!kernel_supports_diff_encode)
|
||||||
@@ -657,6 +728,33 @@ static void set_supported_features(void)
|
|||||||
dfaflags &= ~DFA_CONTROL_DIFF_ENCODE;
|
dfaflags &= ~DFA_CONTROL_DIFF_ENCODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool do_print_cache_dir(aa_features *features, int dirfd, const char *path)
|
||||||
|
{
|
||||||
|
autofree char *cache_dir = NULL;
|
||||||
|
|
||||||
|
cache_dir = aa_policy_cache_dir_path_preview(features, dirfd, path);
|
||||||
|
if (!cache_dir) {
|
||||||
|
PERROR(_("Unable to print the cache directory: %m\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", cache_dir);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool do_print_cache_dirs(aa_features *features, char **cacheloc,
|
||||||
|
int cacheloc_n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < cacheloc_n; i++) {
|
||||||
|
if (!do_print_cache_dir(features, AT_FDCWD, cacheloc[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int process_binary(int option, aa_kernel_interface *kernel_interface,
|
int process_binary(int option, aa_kernel_interface *kernel_interface,
|
||||||
const char *profilename)
|
const char *profilename)
|
||||||
{
|
{
|
||||||
@@ -741,10 +839,11 @@ int test_for_dir_mode(const char *basename, const char *linkdir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int process_profile(int option, aa_kernel_interface *kernel_interface,
|
int process_profile(int option, aa_kernel_interface *kernel_interface,
|
||||||
const char *profilename, const char *cachedir)
|
const char *profilename, aa_policy_cache *pc)
|
||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
autofree const char *cachename = NULL;
|
autofree const char *cachename = NULL;
|
||||||
|
autofree const char *writecachename = NULL;
|
||||||
autofree const char *cachetmpname = NULL;
|
autofree const char *cachetmpname = NULL;
|
||||||
autoclose int cachetmp = -1;
|
autoclose int cachetmp = -1;
|
||||||
const char *basename = NULL;
|
const char *basename = NULL;
|
||||||
@@ -784,9 +883,17 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* setup cachename and tstamp */
|
/* setup cachename and tstamp */
|
||||||
if (!force_complain && !skip_cache) {
|
if (!force_complain && pc) {
|
||||||
cachename = cache_filename(cachedir, basename);
|
cachename = aa_policy_cache_filename(pc, basename);
|
||||||
valid_read_cache(cachename);
|
if (!cachename) {
|
||||||
|
autoclose int fd = aa_policy_cache_open(pc,
|
||||||
|
basename,
|
||||||
|
O_RDONLY);
|
||||||
|
if (fd != -1)
|
||||||
|
pwarn(_("Could not get cachename for '%s'\n"), basename);
|
||||||
|
} else {
|
||||||
|
valid_read_cache(cachename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -818,8 +925,6 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
|
|||||||
if (!retval || skip_bad_cache_rebuild)
|
if (!retval || skip_bad_cache_rebuild)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
cachetmp = setup_cache_tmp(&cachetmpname, cachename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_cache)
|
if (show_cache)
|
||||||
@@ -855,15 +960,27 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pc && write_cache && !force_complain) {
|
||||||
|
writecachename = cache_filename(pc, 0, basename);
|
||||||
|
if (!writecachename) {
|
||||||
|
pwarn("Cache write disabled: Cannot create cache file name '%s': %m\n", basename);
|
||||||
|
write_cache = 0;
|
||||||
|
}
|
||||||
|
cachetmp = setup_cache_tmp(&cachetmpname, writecachename);
|
||||||
|
if (cachetmp == -1) {
|
||||||
|
pwarn("Cache write disabled: Cannot create setup tmp cache file '%s': %m\n", writecachename);
|
||||||
|
write_cache = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* cache file generated by load_policy */
|
/* cache file generated by load_policy */
|
||||||
retval = load_policy(option, kernel_interface, cachetmp);
|
retval = load_policy(option, kernel_interface, cachetmp);
|
||||||
if (retval == 0 && write_cache) {
|
if (retval == 0 && write_cache) {
|
||||||
if (cachetmp == -1) {
|
if (cachetmp == -1) {
|
||||||
unlink(cachetmpname);
|
unlink(cachetmpname);
|
||||||
PERROR("Warning failed to create cache: %s\n",
|
pwarn("Warning failed to create cache: %s\n",
|
||||||
basename);
|
basename);
|
||||||
} else {
|
} else {
|
||||||
install_cache(cachetmpname, cachename);
|
install_cache(cachetmpname, writecachename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
@@ -1005,7 +1122,7 @@ static void setup_parallel_compile(void)
|
|||||||
struct dir_cb_data {
|
struct dir_cb_data {
|
||||||
aa_kernel_interface *kernel_interface;
|
aa_kernel_interface *kernel_interface;
|
||||||
const char *dirname; /* name of the parent dir */
|
const char *dirname; /* name of the parent dir */
|
||||||
const char *cachedir; /* path to the cache sub directory */
|
aa_policy_cache *policy_cache; /* policy_cache to use */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* data - pointer to a dir_cb_data */
|
/* data - pointer to a dir_cb_data */
|
||||||
@@ -1020,7 +1137,7 @@ static int profile_dir_cb(int dirfd unused, const char *name, struct stat *st,
|
|||||||
if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0)
|
if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0)
|
||||||
PERROR(_("Out of memory"));
|
PERROR(_("Out of memory"));
|
||||||
work_spawn(process_profile(option, cb_data->kernel_interface,
|
work_spawn(process_profile(option, cb_data->kernel_interface,
|
||||||
path, cb_data->cachedir),
|
path, cb_data->policy_cache),
|
||||||
handle_work_result);
|
handle_work_result);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1046,17 +1163,17 @@ static int binary_dir_cb(int dirfd unused, const char *name, struct stat *st,
|
|||||||
|
|
||||||
static void setup_flags(void)
|
static void setup_flags(void)
|
||||||
{
|
{
|
||||||
/* Get the match string to determine type of regex support needed */
|
|
||||||
set_supported_features();
|
|
||||||
|
|
||||||
/* Gracefully handle AppArmor kernel without compatibility patch */
|
/* Gracefully handle AppArmor kernel without compatibility patch */
|
||||||
if (!features) {
|
if (!kernel_features && aa_features_new_from_kernel(&kernel_features) == -1) {
|
||||||
PERROR("Cache read/write disabled: interface file missing. "
|
PERROR("Cache read/write disabled: interface file missing. "
|
||||||
"(Kernel needs AppArmor 2.4 compatibility patch.)\n");
|
"(Kernel needs AppArmor 2.4 compatibility patch.)\n");
|
||||||
write_cache = 0;
|
write_cache = 0;
|
||||||
skip_read_cache = 1;
|
skip_read_cache = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the match string to determine type of regex support needed */
|
||||||
|
set_supported_features(kernel_features);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@@ -1092,7 +1209,7 @@ int main(int argc, char *argv[])
|
|||||||
setup_flags();
|
setup_flags();
|
||||||
|
|
||||||
if (!(UNPRIVILEGED_OPS) &&
|
if (!(UNPRIVILEGED_OPS) &&
|
||||||
aa_kernel_interface_new(&kernel_interface, features, apparmorfs) == -1) {
|
aa_kernel_interface_new(&kernel_interface, kernel_features, apparmorfs) == -1) {
|
||||||
PERROR(_("Warning: unable to find a suitable fs in %s, is it "
|
PERROR(_("Warning: unable to find a suitable fs in %s, is it "
|
||||||
"mounted?\nUse --subdomainfs to override.\n"),
|
"mounted?\nUse --subdomainfs to override.\n"),
|
||||||
MOUNTED_FS);
|
MOUNTED_FS);
|
||||||
@@ -1100,18 +1217,28 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((!skip_cache && (write_cache || !skip_read_cache)) ||
|
if ((!skip_cache && (write_cache || !skip_read_cache)) ||
|
||||||
force_clear_cache) {
|
print_cache_dir || force_clear_cache) {
|
||||||
uint16_t max_caches = write_cache && cond_clear_cache ? 1 : 0;
|
uint16_t max_caches = write_cache && cond_clear_cache ? (uint16_t) (-1) : 0;
|
||||||
|
|
||||||
if (!cacheloc && asprintf(&cacheloc, "%s/cache", basedir) == -1) {
|
if (!cacheloc[0]) {
|
||||||
PERROR(_("Memory allocation error."));
|
char *tmp;
|
||||||
return 1;
|
|
||||||
|
if (asprintf(&tmp, "%s/cache.d", basedir) == -1) {
|
||||||
|
PERROR(_("Memory allocation error."));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cacheloc[0] = tmp;
|
||||||
|
cacheloc_n = 1;
|
||||||
}
|
}
|
||||||
|
if (print_cache_dir)
|
||||||
|
return do_print_cache_dirs(kernel_features, cacheloc,
|
||||||
|
cacheloc_n) ? 0 : 1;
|
||||||
|
|
||||||
if (force_clear_cache) {
|
if (force_clear_cache) {
|
||||||
if (aa_policy_cache_remove(AT_FDCWD, cacheloc)) {
|
/* only ever write to the first cacheloc location */
|
||||||
|
if (aa_policy_cache_remove(AT_FDCWD, cacheloc[0])) {
|
||||||
PERROR(_("Failed to clear cache files (%s): %s\n"),
|
PERROR(_("Failed to clear cache files (%s): %s\n"),
|
||||||
cacheloc, strerror(errno));
|
cacheloc[0], strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1121,25 +1248,34 @@ int main(int argc, char *argv[])
|
|||||||
if (create_cache_dir)
|
if (create_cache_dir)
|
||||||
pwarn(_("The --create-cache-dir option is deprecated. Please use --write-cache.\n"));
|
pwarn(_("The --create-cache-dir option is deprecated. Please use --write-cache.\n"));
|
||||||
|
|
||||||
retval = aa_policy_cache_new(&policy_cache, features,
|
retval = aa_policy_cache_new(&policy_cache, kernel_features,
|
||||||
AT_FDCWD, cacheloc, max_caches);
|
AT_FDCWD, cacheloc[0], max_caches);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
if (errno != ENOENT && errno != EEXIST) {
|
if (errno != ENOENT && errno != EEXIST && errno != EROFS) {
|
||||||
PERROR(_("Failed setting up policy cache (%s): %s\n"),
|
PERROR(_("Failed setting up policy cache (%s): %s\n"),
|
||||||
cacheloc, strerror(errno));
|
cacheloc[0], strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_cache) {
|
if (show_cache) {
|
||||||
if (max_caches > 0)
|
if (max_caches > 0)
|
||||||
PERROR("Cache write disabled: Cannot create cache '%s': %m\n",
|
PERROR("Cache write disabled: Cannot create cache '%s': %m\n",
|
||||||
cacheloc);
|
cacheloc[0]);
|
||||||
else
|
else
|
||||||
PERROR("Cache read/write disabled: Policy cache is invalid\n");
|
PERROR("Cache read/write disabled: Policy cache is invalid: %m\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
write_cache = 0;
|
write_cache = 0;
|
||||||
skip_read_cache = 1;
|
} else {
|
||||||
|
if (show_cache)
|
||||||
|
PERROR("Cache: added primary location '%s'\n", cacheloc[0]);
|
||||||
|
for (i = 1; i < cacheloc_n; i++) {
|
||||||
|
if (aa_policy_cache_add_ro_dir(policy_cache, AT_FDCWD,
|
||||||
|
cacheloc[i])) {
|
||||||
|
pwarn("Cache: failed to add read only location '%s', does not contain valid cache directory for the specified feature set\n", cacheloc[i]);
|
||||||
|
} else if (show_cache)
|
||||||
|
pwarn("Cache: added readonly location '%s'\n", cacheloc[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1170,7 +1306,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
memset(&cb_data, 0, sizeof(struct dir_cb_data));
|
memset(&cb_data, 0, sizeof(struct dir_cb_data));
|
||||||
cb_data.dirname = profilename;
|
cb_data.dirname = profilename;
|
||||||
cb_data.cachedir = cacheloc;
|
cb_data.policy_cache = policy_cache;
|
||||||
cb_data.kernel_interface = kernel_interface;
|
cb_data.kernel_interface = kernel_interface;
|
||||||
cb = binary_input ? binary_dir_cb : profile_dir_cb;
|
cb = binary_input ? binary_dir_cb : profile_dir_cb;
|
||||||
if ((retval = dirat_for_each(AT_FDCWD, profilename,
|
if ((retval = dirat_for_each(AT_FDCWD, profilename,
|
||||||
@@ -1184,7 +1320,7 @@ int main(int argc, char *argv[])
|
|||||||
handle_work_result);
|
handle_work_result);
|
||||||
} else {
|
} else {
|
||||||
work_spawn(process_profile(option, kernel_interface,
|
work_spawn(process_profile(option, kernel_interface,
|
||||||
profilename, cacheloc),
|
profilename, policy_cache),
|
||||||
handle_work_result);
|
handle_work_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
217
parser/po/de.po
217
parser/po/de.po
@@ -6,24 +6,24 @@ msgstr ""
|
|||||||
"Project-Id-Version: apparmor-parser\n"
|
"Project-Id-Version: apparmor-parser\n"
|
||||||
"Report-Msgid-Bugs-To: <apparmor@lists.ubuntu.com>\n"
|
"Report-Msgid-Bugs-To: <apparmor@lists.ubuntu.com>\n"
|
||||||
"POT-Creation-Date: 2014-09-13 00:11-0700\n"
|
"POT-Creation-Date: 2014-09-13 00:11-0700\n"
|
||||||
"PO-Revision-Date: 2015-09-05 20:55+0000\n"
|
"PO-Revision-Date: 2018-04-06 14:39+0000\n"
|
||||||
"Last-Translator: Tobias Bannert <tobannert@gmail.com>\n"
|
"Last-Translator: Tobias Bannert <tobannert@gmail.com>\n"
|
||||||
"Language-Team: Novell Language <language@novell.com>\n"
|
"Language-Team: Novell Language <language@novell.com>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Launchpad-Export-Date: 2016-06-01 05:15+0000\n"
|
"X-Launchpad-Export-Date: 2018-04-07 05:20+0000\n"
|
||||||
"X-Generator: Launchpad (build 18053)\n"
|
"X-Generator: Launchpad (build 18599)\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
|
|
||||||
#: ../parser_include.c:113
|
#: ../parser_include.c:113 ../parser_include.c:111
|
||||||
msgid "Error: Out of memory.\n"
|
msgid "Error: Out of memory.\n"
|
||||||
msgstr "Fehler: Kein Speicher vorhanden.\n"
|
msgstr "Fehler: nicht genügend Speicher!\n"
|
||||||
|
|
||||||
#: ../parser_include.c:123
|
#: ../parser_include.c:123 ../parser_include.c:121
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: basedir %s is not a directory, skipping.\n"
|
msgid "Error: basedir %s is not a directory, skipping.\n"
|
||||||
msgstr "Fehler: basedir »%s« ist kein Verzeichnis - es wird übersprungen.\n"
|
msgstr "Fehler: basedir »%s« ist kein Verzeichnis, es wird übersprungen.\n"
|
||||||
|
|
||||||
#: ../parser_include.c:137
|
#: ../parser_include.c:137
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -31,99 +31,108 @@ msgid "Error: Could not add directory %s to search path.\n"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Fehler: Verzeichnis »%s« konnte nicht zu Suchpfad hinzugefügt werden.\n"
|
"Fehler: Verzeichnis »%s« konnte nicht zu Suchpfad hinzugefügt werden.\n"
|
||||||
|
|
||||||
#: ../parser_include.c:147
|
#: ../parser_include.c:147 ../parser_include.c:151
|
||||||
msgid "Error: Could not allocate memory.\n"
|
msgid "Error: Could not allocate memory.\n"
|
||||||
msgstr "Fehler: Es konnte kein Speicher zugeordnet werden.\n"
|
msgstr "Fehler: Es konnte kein Speicher zugeordnet werden.\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:69 ../parser_interface.c:72
|
#: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49
|
||||||
msgid "Bad write position\n"
|
msgid "Bad write position\n"
|
||||||
msgstr "Ungültige Schreibposition\n"
|
msgstr "Ungültige Schreibposition\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:72 ../parser_interface.c:75
|
#: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52
|
||||||
msgid "Permission denied\n"
|
msgid "Permission denied\n"
|
||||||
msgstr "Zugriff verweigert\n"
|
msgstr "Zugriff verweigert\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:75 ../parser_interface.c:78
|
#: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55
|
||||||
msgid "Out of memory\n"
|
msgid "Out of memory\n"
|
||||||
msgstr "Kein Speicher vorhanden\n"
|
msgstr "Nicht genügend Speicher!\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:78 ../parser_interface.c:81
|
#: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58
|
||||||
msgid "Couldn't copy profile: Bad memory address\n"
|
msgid "Couldn't copy profile: Bad memory address\n"
|
||||||
msgstr "Profil konnte nicht kopiert werden: Keine Speicheradresse\n"
|
msgstr "Profil konnte nicht kopiert werden: falsche Speicheradresse\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:81 ../parser_interface.c:84
|
#: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61
|
||||||
msgid "Profile doesn't conform to protocol\n"
|
msgid "Profile doesn't conform to protocol\n"
|
||||||
msgstr "Das Profil entspricht nicht dem Protokoll\n"
|
msgstr "Das Profil entspricht nicht dem Protokoll\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:84 ../parser_interface.c:87
|
#: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64
|
||||||
msgid "Profile does not match signature\n"
|
msgid "Profile does not match signature\n"
|
||||||
msgstr "Das Profil stimmt nicht mit der Signatur überein\n"
|
msgstr "Das Profil stimmt nicht mit der Signatur überein\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:87 ../parser_interface.c:90
|
#: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67
|
||||||
msgid "Profile version not supported by Apparmor module\n"
|
msgid "Profile version not supported by Apparmor module\n"
|
||||||
msgstr "Profilversion wird vom Apparmor-Modul nicht unterstützt\n"
|
msgstr "Profilversion wird vom Apparmor-Modul nicht unterstützt\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:90 ../parser_interface.c:93
|
#: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70
|
||||||
msgid "Profile already exists\n"
|
msgid "Profile already exists\n"
|
||||||
msgstr "Profil ist bereits vorhanden\n"
|
msgstr "Profil ist bereits vorhanden\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:93 ../parser_interface.c:96
|
#: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73
|
||||||
msgid "Profile doesn't exist\n"
|
msgid "Profile doesn't exist\n"
|
||||||
msgstr "Profil ist nicht vorhanden\n"
|
msgstr "Profil ist nicht vorhanden\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:96 ../parser_interface.c:99
|
#: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76
|
||||||
msgid "Permission denied; attempted to load a profile while confined?\n"
|
msgid "Permission denied; attempted to load a profile while confined?\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Zugriff verweigert! Haben Sie versucht ein Profil zu laden, während Sie "
|
"Zugriff verweigert! Haben Sie versucht ein Profil zu laden, während Sie "
|
||||||
"eingeschränkt waren?\n"
|
"eingeschränkt waren?\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:99 ../parser_interface.c:102
|
#: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unknown error (%d): %s\n"
|
msgid "Unknown error (%d): %s\n"
|
||||||
msgstr "Unbekannter Fehler (%d): %s\n"
|
msgstr "Unbekannter Fehler (%d): %s\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:116 ../parser_interface.c:119
|
#: ../parser_interface.c:116 ../parser_interface.c:119
|
||||||
|
#: ../parser_interface.c:96
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Unable to add \"%s\". "
|
msgid "%s: Unable to add \"%s\". "
|
||||||
msgstr "%s: Hinzufügen von »%s« nicht möglich. "
|
msgstr "%s: Hinzufügen von »%s« nicht möglich. "
|
||||||
|
|
||||||
#: ../parser_interface.c:121 ../parser_interface.c:124
|
#: ../parser_interface.c:121 ../parser_interface.c:124
|
||||||
|
#: ../parser_interface.c:101
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Unable to replace \"%s\". "
|
msgid "%s: Unable to replace \"%s\". "
|
||||||
msgstr "%s: »%s« kann nicht ersetzt werden. "
|
msgstr "%s: »%s« kann nicht ersetzt werden. "
|
||||||
|
|
||||||
#: ../parser_interface.c:126 ../parser_interface.c:129
|
#: ../parser_interface.c:126 ../parser_interface.c:129
|
||||||
|
#: ../parser_interface.c:106
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Unable to remove \"%s\". "
|
msgid "%s: Unable to remove \"%s\". "
|
||||||
msgstr "%s: »%s« kann nicht entfernt werden. "
|
msgstr "%s: »%s« kann nicht entfernt werden. "
|
||||||
|
|
||||||
#: ../parser_interface.c:131 ../parser_interface.c:134
|
#: ../parser_interface.c:131 ../parser_interface.c:134
|
||||||
|
#: ../parser_interface.c:111
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Unable to write to stdout\n"
|
msgid "%s: Unable to write to stdout\n"
|
||||||
msgstr "%s: Schreiben in Standardausgabe nicht möglich\n"
|
msgstr "%s: Schreiben in Standardausgabe nicht möglich\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:135 ../parser_interface.c:138
|
#: ../parser_interface.c:135 ../parser_interface.c:138
|
||||||
|
#: ../parser_interface.c:115
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Unable to write to output file\n"
|
msgid "%s: Unable to write to output file\n"
|
||||||
msgstr "%s: Schreiben in Ausgabedatei nicht möglich\n"
|
msgstr "%s: Schreiben in Ausgabedatei nicht möglich\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:138 ../parser_interface.c:162
|
#: ../parser_interface.c:138 ../parser_interface.c:162
|
||||||
#: ../parser_interface.c:141 ../parser_interface.c:165
|
#: ../parser_interface.c:141 ../parser_interface.c:165
|
||||||
|
#: ../parser_interface.c:118 ../parser_interface.c:142
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: ASSERT: Invalid option: %d\n"
|
msgid "%s: ASSERT: Invalid option: %d\n"
|
||||||
msgstr "%s: ASSERT: Ungültige Option: %d\n"
|
msgstr "%s: ASSERT: Ungültige Option: %d\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:147 ../parser_interface.c:150
|
#: ../parser_interface.c:147 ../parser_interface.c:150
|
||||||
|
#: ../parser_interface.c:127
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Addition succeeded for \"%s\".\n"
|
msgid "Addition succeeded for \"%s\".\n"
|
||||||
msgstr "Hinzufügen für »%s« erfolgreich.\n"
|
msgstr "Hinzufügen für »%s« erfolgreich.\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:151 ../parser_interface.c:154
|
#: ../parser_interface.c:151 ../parser_interface.c:154
|
||||||
|
#: ../parser_interface.c:131
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Replacement succeeded for \"%s\".\n"
|
msgid "Replacement succeeded for \"%s\".\n"
|
||||||
msgstr "Ersetzungsvorgang für »%s« erfolgreich.\n"
|
msgstr "Ersetzungsvorgang für »%s« erfolgreich.\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:155 ../parser_interface.c:158
|
#: ../parser_interface.c:155 ../parser_interface.c:158
|
||||||
|
#: ../parser_interface.c:135
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Removal succeeded for \"%s\".\n"
|
msgid "Removal succeeded for \"%s\".\n"
|
||||||
msgstr "Entfernen für »%s« erfolgreich.\n"
|
msgstr "Entfernen für »%s« erfolgreich.\n"
|
||||||
@@ -136,6 +145,7 @@ msgstr ""
|
|||||||
"Auflösung %p\n"
|
"Auflösung %p\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:656 ../parser_interface.c:658
|
#: ../parser_interface.c:656 ../parser_interface.c:658
|
||||||
|
#: ../parser_interface.c:446
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "profile %s network rules not enforced\n"
|
msgid "profile %s network rules not enforced\n"
|
||||||
msgstr "Netzwerkregeln für Profil %s werden nicht erzwungen\n"
|
msgstr "Netzwerkregeln für Profil %s werden nicht erzwungen\n"
|
||||||
@@ -146,16 +156,19 @@ msgstr "Unbekannter Mustertyp\n"
|
|||||||
|
|
||||||
#: ../parser_interface.c:750 ../parser_interface.c:902
|
#: ../parser_interface.c:750 ../parser_interface.c:902
|
||||||
#: ../parser_interface.c:743 ../parser_interface.c:894
|
#: ../parser_interface.c:743 ../parser_interface.c:894
|
||||||
|
#: ../parser_interface.c:518 ../parser_interface.c:669
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unable to open %s - %s\n"
|
msgid "Unable to open %s - %s\n"
|
||||||
msgstr "%s kann nicht geöffnet werden - %s\n"
|
msgstr "%s kann nicht geöffnet werden – %s\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:776 ../parser_interface.c:768
|
#: ../parser_interface.c:776 ../parser_interface.c:768
|
||||||
|
#: ../parser_interface.c:543
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Memory Allocation Error: Unable to remove ^%s\n"
|
msgid "Memory Allocation Error: Unable to remove ^%s\n"
|
||||||
msgstr "Speicherzuordnungsfehler: ^%s kann nicht entfernt werden\n"
|
msgstr "Speicherzuordnungsfehler: ^%s kann nicht entfernt werden\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:789 ../parser_interface.c:781
|
#: ../parser_interface.c:789 ../parser_interface.c:781
|
||||||
|
#: ../parser_interface.c:556
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Memory Allocation Error: Unable to remove %s:%s."
|
msgid "Memory Allocation Error: Unable to remove %s:%s."
|
||||||
msgstr "Speicherzuordnungsfehler: %s:%s kann nicht entfernt werden."
|
msgstr "Speicherzuordnungsfehler: %s:%s kann nicht entfernt werden."
|
||||||
@@ -171,22 +184,24 @@ msgstr "Serialisierung von Profil %s nicht möglich\n"
|
|||||||
|
|
||||||
#: ../parser_interface.c:829 ../parser_interface.c:916
|
#: ../parser_interface.c:829 ../parser_interface.c:916
|
||||||
#: ../parser_interface.c:821 ../parser_interface.c:908
|
#: ../parser_interface.c:821 ../parser_interface.c:908
|
||||||
|
#: ../parser_interface.c:582
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Unable to write entire profile entry\n"
|
msgid "%s: Unable to write entire profile entry\n"
|
||||||
msgstr "%s: Profileintrag kann nicht geschrieben werden\n"
|
msgstr "%s: Profileintrag kann nicht geschrieben werden\n"
|
||||||
|
|
||||||
#: ../parser_interface.c:839 ../parser_interface.c:831
|
#: ../parser_interface.c:839 ../parser_interface.c:831
|
||||||
|
#: ../parser_interface.c:593
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Unable to write entire profile entry to cache\n"
|
msgid "%s: Unable to write entire profile entry to cache\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"%s: Schreiben des gesamten Profileintrags in den Puffer nicht möglich\n"
|
"%s: Schreiben des gesamten Profileintrags in den Puffer nicht möglich\n"
|
||||||
|
|
||||||
#: parser_lex.l:100 parser_lex.l:163
|
#: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Could not open '%s'"
|
msgid "Could not open '%s'"
|
||||||
msgstr "»%s« konnte nicht geöffnet werden"
|
msgstr "»%s« konnte nicht geöffnet werden"
|
||||||
|
|
||||||
#: parser_lex.l:104 parser_lex.l:167
|
#: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "fstat failed for '%s'"
|
msgid "fstat failed for '%s'"
|
||||||
msgstr "fstat fehlgeschlagen für »%s«"
|
msgstr "fstat fehlgeschlagen für »%s«"
|
||||||
@@ -201,18 +216,18 @@ msgstr "opendir fehlgeschlagen für »%s«"
|
|||||||
msgid "stat failed for '%s'"
|
msgid "stat failed for '%s'"
|
||||||
msgstr "stat fehlgeschlagen für »%s«"
|
msgstr "stat fehlgeschlagen für »%s«"
|
||||||
|
|
||||||
#: parser_lex.l:155 parser_lex.l:133
|
#: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Could not open '%s' in '%s'"
|
msgid "Could not open '%s' in '%s'"
|
||||||
msgstr "»%s« konnte nicht in »%s« geöffnet werden"
|
msgstr "»%s« konnte nicht in »%s« geöffnet werden"
|
||||||
|
|
||||||
#: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399
|
#: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399
|
||||||
#: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586
|
#: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Found unexpected character: '%s'"
|
msgid "Found unexpected character: '%s'"
|
||||||
msgstr "Unerwartetes Zeichen gefunden: »%s«"
|
msgstr "Unerwartetes Zeichen gefunden: »%s«"
|
||||||
|
|
||||||
#: parser_lex.l:386 parser_lex.l:418
|
#: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428
|
||||||
msgid "Variable declarations do not accept trailing commas"
|
msgid "Variable declarations do not accept trailing commas"
|
||||||
msgstr "Variablendeklarationen dürfen nicht mit Kommata enden"
|
msgstr "Variablendeklarationen dürfen nicht mit Kommata enden"
|
||||||
|
|
||||||
@@ -221,7 +236,7 @@ msgstr "Variablendeklarationen dürfen nicht mit Kommata enden"
|
|||||||
msgid "(network_mode) Found unexpected character: '%s'"
|
msgid "(network_mode) Found unexpected character: '%s'"
|
||||||
msgstr "(network_mode) Unerwartetes Zeichen gefunden: »%s«"
|
msgstr "(network_mode) Unerwartetes Zeichen gefunden: »%s«"
|
||||||
|
|
||||||
#: ../parser_main.c:333 ../parser_common.c:61
|
#: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Warning from %s (%s%sline %d): %s"
|
msgid "Warning from %s (%s%sline %d): %s"
|
||||||
msgstr "Warnung aus %s (%s%sZeile %d): %s"
|
msgstr "Warnung aus %s (%s%sZeile %d): %s"
|
||||||
@@ -233,7 +248,7 @@ msgstr ""
|
|||||||
"%s: Dem Einhängepunkt der Unterdomänenbasis konnte kein Speicher zugeordnet "
|
"%s: Dem Einhängepunkt der Unterdomänenbasis konnte kein Speicher zugeordnet "
|
||||||
"werden\n"
|
"werden\n"
|
||||||
|
|
||||||
#: ../parser_main.c:577 ../parser_main.c:616
|
#: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Warning: unable to find a suitable fs in %s, is it mounted?\n"
|
"Warning: unable to find a suitable fs in %s, is it mounted?\n"
|
||||||
@@ -243,7 +258,7 @@ msgstr ""
|
|||||||
"es eingehängt?\n"
|
"es eingehängt?\n"
|
||||||
"Verwenden Sie --subdomainfs, um es außer Kraft zu setzen.\n"
|
"Verwenden Sie --subdomainfs, um es außer Kraft zu setzen.\n"
|
||||||
|
|
||||||
#: ../parser_main.c:597 ../parser_main.c:635
|
#: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%s: Sorry. You need root privileges to run this program.\n"
|
"%s: Sorry. You need root privileges to run this program.\n"
|
||||||
@@ -252,7 +267,7 @@ msgstr ""
|
|||||||
"»%s«: Sie benötigen Systemverwalterrechte zum Ausführen dieses Programms.\n"
|
"»%s«: Sie benötigen Systemverwalterrechte zum Ausführen dieses Programms.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
||||||
#: ../parser_main.c:604 ../parser_main.c:642
|
#: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%s: Warning! You've set this program setuid root.\n"
|
"%s: Warning! You've set this program setuid root.\n"
|
||||||
@@ -265,7 +280,7 @@ msgstr ""
|
|||||||
"\n"
|
"\n"
|
||||||
|
|
||||||
#: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836
|
#: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836
|
||||||
#: ../parser_main.c:946
|
#: ../parser_main.c:946 ../parser_main.c:860
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Error: Could not read profile %s: %s.\n"
|
msgid "Error: Could not read profile %s: %s.\n"
|
||||||
msgstr "Fehler: Profil »%s« konnte nicht gelesen werden: »%s«.\n"
|
msgstr "Fehler: Profil »%s« konnte nicht gelesen werden: »%s«.\n"
|
||||||
@@ -281,26 +296,33 @@ msgstr "Fehler: Profil »%s« konnte nicht gelesen werden: »%s«.\n"
|
|||||||
#: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092
|
#: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092
|
||||||
#: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234
|
#: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234
|
||||||
#: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385
|
#: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385
|
||||||
|
#: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133
|
||||||
|
#: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472
|
||||||
|
#: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130
|
||||||
|
#: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190
|
||||||
|
#: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490
|
||||||
|
#: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639
|
||||||
|
#: ../network.c:314 ../af_unix.cc:203
|
||||||
msgid "Memory allocation error."
|
msgid "Memory allocation error."
|
||||||
msgstr "Speicherzuordnungsfehler."
|
msgstr "Speicherzuordnungsfehler."
|
||||||
|
|
||||||
#: ../parser_main.c:740 ../parser_main.c:872
|
#: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Cached load succeeded for \"%s\".\n"
|
msgid "Cached load succeeded for \"%s\".\n"
|
||||||
msgstr "Zwischengespeichertes Laden für »%s« erfolgreich.\n"
|
msgstr "Zwischengespeichertes Laden für »%s« erfolgreich.\n"
|
||||||
|
|
||||||
#: ../parser_main.c:744 ../parser_main.c:876
|
#: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Cached reload succeeded for \"%s\".\n"
|
msgid "Cached reload succeeded for \"%s\".\n"
|
||||||
msgstr "Zwischengespeichertes Neuladen für »%s« erfolgreich.\n"
|
msgstr "Zwischengespeichertes Neuladen für »%s« erfolgreich.\n"
|
||||||
|
|
||||||
#: ../parser_main.c:910 ../parser_main.c:1058
|
#: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Errors found in file. Aborting.\n"
|
msgid "%s: Errors found in file. Aborting.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"%s: In der Datei wurde ein Fehler gefunden. Der Vorgang wird abgebrochen.\n"
|
"%s: In der Datei wurde ein Fehler gefunden. Der Vorgang wird abgebrochen.\n"
|
||||||
|
|
||||||
#: ../parser_misc.c:426 ../parser_misc.c:597
|
#: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339
|
||||||
msgid ""
|
msgid ""
|
||||||
"Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n"
|
"Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n"
|
||||||
"See the apparmor.d(5) manpage for details.\n"
|
"See the apparmor.d(5) manpage for details.\n"
|
||||||
@@ -310,17 +332,17 @@ msgstr ""
|
|||||||
"Weitere Informationen auf der Handbuchseite apparmor.d(5).\n"
|
"Weitere Informationen auf der Handbuchseite apparmor.d(5).\n"
|
||||||
|
|
||||||
#: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638
|
#: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638
|
||||||
#: ../parser_misc.c:645
|
#: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387
|
||||||
msgid "Conflict 'a' and 'w' perms are mutually exclusive."
|
msgid "Conflict 'a' and 'w' perms are mutually exclusive."
|
||||||
msgstr "Die Parameter »a« und »w« schließen sich gegenseitig aus."
|
msgstr "Die Parameter »a« und »w« schließen sich gegenseitig aus."
|
||||||
|
|
||||||
#: ../parser_misc.c:491 ../parser_misc.c:662
|
#: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404
|
||||||
msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified"
|
msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ausführungskennzeichner »i« ist ungültig, ein Kennzeichner, mit dem ein "
|
"Ausführungskennzeichner »i« ist ungültig, ein Kennzeichner, mit dem ein "
|
||||||
"Konflikt besteht, wurde bereits angegeben."
|
"Konflikt besteht, wurde bereits angegeben."
|
||||||
|
|
||||||
#: ../parser_misc.c:502 ../parser_misc.c:673
|
#: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Unconfined exec qualifier (%c%c) allows some dangerous environment variables "
|
"Unconfined exec qualifier (%c%c) allows some dangerous environment variables "
|
||||||
@@ -331,7 +353,7 @@ msgstr ""
|
|||||||
"Einzelheiten mit »man 5 apparmor.d«.\n"
|
"Einzelheiten mit »man 5 apparmor.d«.\n"
|
||||||
|
|
||||||
#: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681
|
#: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681
|
||||||
#: ../parser_misc.c:722
|
#: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified"
|
msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -339,7 +361,7 @@ msgstr ""
|
|||||||
"Konflikt besteht, wurde bereits angegeben."
|
"Konflikt besteht, wurde bereits angegeben."
|
||||||
|
|
||||||
#: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708
|
#: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708
|
||||||
#: ../parser_misc.c:716
|
#: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Exec qualifier '%c%c' invalid, conflicting qualifier already specified"
|
"Exec qualifier '%c%c' invalid, conflicting qualifier already specified"
|
||||||
@@ -347,12 +369,12 @@ msgstr ""
|
|||||||
"Ausführungskennzeichner »%c%c« ist ungültig, ein Kennzeichner, mit dem ein "
|
"Ausführungskennzeichner »%c%c« ist ungültig, ein Kennzeichner, mit dem ein "
|
||||||
"Konflikt besteht, wurde bereits angegeben."
|
"Konflikt besteht, wurde bereits angegeben."
|
||||||
|
|
||||||
#: ../parser_misc.c:593 ../parser_misc.c:764
|
#: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Internal: unexpected mode character '%c' in input"
|
msgid "Internal: unexpected mode character '%c' in input"
|
||||||
msgstr "Intern: Unerwartetes Moduszeichen »%c« in der Eingabe"
|
msgstr "Intern: Unerwartetes Moduszeichen »%c« in der Eingabe"
|
||||||
|
|
||||||
#: ../parser_misc.c:615 ../parser_misc.c:786
|
#: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Internal error generated invalid perm 0x%llx\n"
|
msgid "Internal error generated invalid perm 0x%llx\n"
|
||||||
msgstr "Interner Fehler erzeugte ungültige Zugriffsrechte 0x%llx\n"
|
msgstr "Interner Fehler erzeugte ungültige Zugriffsrechte 0x%llx\n"
|
||||||
@@ -363,68 +385,69 @@ msgstr "Interner Fehler erzeugte ungültige Zugriffsrechte 0x%llx\n"
|
|||||||
msgid "AppArmor parser error: %s\n"
|
msgid "AppArmor parser error: %s\n"
|
||||||
msgstr "AppArmor-Analysefehler: %s\n"
|
msgstr "AppArmor-Analysefehler: %s\n"
|
||||||
|
|
||||||
#: ../parser_merge.c:92 ../parser_merge.c:91
|
#: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83
|
||||||
msgid "Couldn't merge entries. Out of Memory\n"
|
msgid "Couldn't merge entries. Out of Memory\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Einträge konnten nicht zusammengeführt werden. Kein Speicher vorhanden\n"
|
"Einträge konnten nicht zusammengeführt werden. Kein Speicher vorhanden\n"
|
||||||
|
|
||||||
#: ../parser_merge.c:111 ../parser_merge.c:113
|
#: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "profile %s: has merged rule %s with conflicting x modifiers\n"
|
msgid "profile %s: has merged rule %s with conflicting x modifiers\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Profil %s: enthält zusammengeführte Regel %s mit in Konflikt stehenden x-"
|
"Profil %s: enthält zusammengeführte Regel %s mit in Konflikt stehenden x-"
|
||||||
"Modifizierern\n"
|
"Modifizierern\n"
|
||||||
|
|
||||||
#: parser_yacc.y:236 parser_yacc.y:277
|
#: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320
|
||||||
msgid "Profile attachment must begin with a '/'."
|
msgid "Profile attachment must begin with a '/'."
|
||||||
msgstr "Profilanhang muss mit einem »/« beginnen."
|
msgstr "Profilanhang muss mit einem »/« beginnen."
|
||||||
|
|
||||||
#: parser_yacc.y:260 parser_yacc.y:302
|
#: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348
|
||||||
msgid ""
|
msgid ""
|
||||||
"Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'."
|
"Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Profilnamen müssen mit einem »/«, Namensraum oder dem Schlüsselwort "
|
"Profilnamen müssen mit einem »/«, Namensraum oder dem Schlüsselwort "
|
||||||
"»profile« oder »hat« beginnen."
|
"»profile« oder »hat« beginnen."
|
||||||
|
|
||||||
#: parser_yacc.y:296 parser_yacc.y:338
|
#: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Failed to create alias %s -> %s\n"
|
msgid "Failed to create alias %s -> %s\n"
|
||||||
msgstr "Alias %s → %s konnte nicht erstellt werden\n"
|
msgstr "Alias %s → %s konnte nicht erstellt werden\n"
|
||||||
|
|
||||||
#: parser_yacc.y:417 parser_yacc.y:460
|
#: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506
|
||||||
msgid "Profile flag chroot_relative conflicts with namespace_relative"
|
msgid "Profile flag chroot_relative conflicts with namespace_relative"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Profil-Marker chroot_relative steht in Konflikt mit namespace_relative"
|
"Profil-Marker chroot_relative steht in Konflikt mit namespace_relative"
|
||||||
|
|
||||||
#: parser_yacc.y:421 parser_yacc.y:464
|
#: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510
|
||||||
msgid "Profile flag mediate_deleted conflicts with delegate_deleted"
|
msgid "Profile flag mediate_deleted conflicts with delegate_deleted"
|
||||||
msgstr "Profil-Marker mediate_deleted steht in Konflikt mit delegate_deleted"
|
msgstr "Profil-Marker mediate_deleted steht in Konflikt mit delegate_deleted"
|
||||||
|
|
||||||
#: parser_yacc.y:424 parser_yacc.y:467
|
#: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513
|
||||||
msgid ""
|
msgid ""
|
||||||
"Profile flag attach_disconnected conflicts with no_attach_disconnected"
|
"Profile flag attach_disconnected conflicts with no_attach_disconnected"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Profil-Marker attach_disconnected steht in Konflikt mit "
|
"Profil-Marker attach_disconnected steht in Konflikt mit "
|
||||||
"no_attach_disconnected"
|
"no_attach_disconnected"
|
||||||
|
|
||||||
#: parser_yacc.y:427 parser_yacc.y:470
|
#: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516
|
||||||
msgid "Profile flag chroot_attach conflicts with chroot_no_attach"
|
msgid "Profile flag chroot_attach conflicts with chroot_no_attach"
|
||||||
msgstr "Profil-Marker chroot_attach steht in Konflikt mit chroot_no_attach"
|
msgstr "Profil-Marker chroot_attach steht in Konflikt mit chroot_no_attach"
|
||||||
|
|
||||||
#: parser_yacc.y:441 parser_yacc.y:484
|
#: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530
|
||||||
msgid "Profile flag 'debug' is no longer valid."
|
msgid "Profile flag 'debug' is no longer valid."
|
||||||
msgstr "Profil-Marker »debug« ist nicht mehr gültig."
|
msgstr "Profil-Marker »debug« ist nicht mehr gültig."
|
||||||
|
|
||||||
#: parser_yacc.y:463 parser_yacc.y:506
|
#: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Invalid profile flag: %s."
|
msgid "Invalid profile flag: %s."
|
||||||
msgstr "Ungültiger Profil-Marker: %s."
|
msgstr "Ungültiger Profil-Marker: %s."
|
||||||
|
|
||||||
#: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548
|
#: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594
|
||||||
msgid "Assert: `rule' returned NULL."
|
msgid "Assert: `rule' returned NULL."
|
||||||
msgstr "Assert: Für »rule« wurde NULL zurückgegeben."
|
msgstr "Assert: Für »rule« wurde NULL zurückgegeben."
|
||||||
|
|
||||||
#: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584
|
#: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584
|
||||||
|
#: parser_yacc.y:598 parser_yacc.y:630
|
||||||
msgid ""
|
msgid ""
|
||||||
"Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', "
|
"Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', "
|
||||||
"'p', or 'u'"
|
"'p', or 'u'"
|
||||||
@@ -432,80 +455,81 @@ msgstr ""
|
|||||||
"Ungültiger Modus, in den Verweigernregeln darf vor »x« keiner der "
|
"Ungültiger Modus, in den Verweigernregeln darf vor »x« keiner der "
|
||||||
"Ausführungskennzeichner »i«, »p« oder »u« stehen"
|
"Ausführungskennzeichner »i«, »p« oder »u« stehen"
|
||||||
|
|
||||||
#: parser_yacc.y:524 parser_yacc.y:556
|
#: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602
|
||||||
msgid ""
|
msgid ""
|
||||||
"Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'"
|
"Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ungültiger Modus, in Verbotsregeln muss vor »x« einer der exec-Qualifier "
|
"Ungültiger Modus, in Verbotsregeln muss vor »x« einer der exec-Qualifier "
|
||||||
"»i«, »p«, »c« oder »u« stehen"
|
"»i«, »p«, »c« oder »u« stehen"
|
||||||
|
|
||||||
#: parser_yacc.y:549 parser_yacc.y:587
|
#: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633
|
||||||
msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'"
|
msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ungültiger Modus, in Verbotsregeln muss vor »x« einer der exec-Qualifier "
|
"Ungültiger Modus, in Verbotsregeln muss vor »x« einer der exec-Qualifier "
|
||||||
"»i«, »p« oder »u« stehen"
|
"»i«, »p« oder »u« stehen"
|
||||||
|
|
||||||
#: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614
|
#: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660
|
||||||
msgid "Assert: `network_rule' return invalid protocol."
|
msgid "Assert: `network_rule' return invalid protocol."
|
||||||
msgstr "Assert: Für »network_rule« wurde NULL zurückgegeben."
|
msgstr "Assert: Für »network_rule« wurde NULL zurückgegeben."
|
||||||
|
|
||||||
#: parser_yacc.y:649 parser_yacc.y:696
|
#: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786
|
||||||
msgid "Assert: `change_profile' returned NULL."
|
msgid "Assert: `change_profile' returned NULL."
|
||||||
msgstr "Assert: Für »change_profile« wurde NULL zurückgegeben."
|
msgstr "Assert: Für »change_profile« wurde NULL zurückgegeben."
|
||||||
|
|
||||||
#: parser_yacc.y:680 parser_yacc.y:720
|
#: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810
|
||||||
msgid "Assert: 'hat rule' returned NULL."
|
msgid "Assert: 'hat rule' returned NULL."
|
||||||
msgstr "Assert: Für »hat rule« wurde NULL zurückgegeben."
|
msgstr "Assert: Für »hat rule« wurde NULL zurückgegeben."
|
||||||
|
|
||||||
#: parser_yacc.y:689 parser_yacc.y:729
|
#: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819
|
||||||
msgid "Assert: 'local_profile rule' returned NULL."
|
msgid "Assert: 'local_profile rule' returned NULL."
|
||||||
msgstr "Assert: Für »local_profile rule« wurde NULL zurückgegeben."
|
msgstr "Assert: Für »local_profile rule« wurde NULL zurückgegeben."
|
||||||
|
|
||||||
#: parser_yacc.y:824 parser_yacc.y:885
|
#: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unset boolean variable %s used in if-expression"
|
msgid "Unset boolean variable %s used in if-expression"
|
||||||
msgstr "In Bedingungssatz verwendete Boolsche-Variable »%s« deaktivieren"
|
msgstr "In Bedingungssatz verwendete Boolsche-Variable »%s« deaktivieren"
|
||||||
|
|
||||||
#: parser_yacc.y:882 parser_yacc.y:986
|
#: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092
|
||||||
msgid "unsafe rule missing exec permissions"
|
msgid "unsafe rule missing exec permissions"
|
||||||
msgstr "Fehlende Ausführungsrechte bei unsicherer Regel"
|
msgstr "Fehlende Ausführungsrechte bei unsicherer Regel"
|
||||||
|
|
||||||
#: parser_yacc.y:901 parser_yacc.y:954
|
#: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060
|
||||||
msgid "subset can only be used with link rules."
|
msgid "subset can only be used with link rules."
|
||||||
msgstr "subset kann nur mit Link-Regeln verwendet werden."
|
msgstr "subset kann nur mit Link-Regeln verwendet werden."
|
||||||
|
|
||||||
#: parser_yacc.y:903 parser_yacc.y:956
|
#: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062
|
||||||
msgid "link and exec perms conflict on a file rule using ->"
|
msgid "link and exec perms conflict on a file rule using ->"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Verknüpfungs- und Ausführungsberechtigungen stehen in Konflikt mit einer "
|
"Verknüpfungs- und Ausführungsberechtigungen stehen in Konflikt mit einer "
|
||||||
"Dateiregel, in der »->« verwendet wird"
|
"Dateiregel, in der »->« verwendet wird"
|
||||||
|
|
||||||
#: parser_yacc.y:905 parser_yacc.y:958
|
#: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064
|
||||||
msgid "link perms are not allowed on a named profile transition.\n"
|
msgid "link perms are not allowed on a named profile transition.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Verknüpfungsberechtigungen sind bei einem benannten Profilübergang nicht "
|
"Verknüpfungsberechtigungen sind bei einem benannten Profilübergang nicht "
|
||||||
"erlaubt.\n"
|
"erlaubt.\n"
|
||||||
|
|
||||||
#: parser_yacc.y:921 parser_yacc.y:1003
|
#: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "missing an end of line character? (entry: %s)"
|
msgid "missing an end of line character? (entry: %s)"
|
||||||
msgstr "Fehlt ein Zeilenumbruch? (Eintrag: %s)"
|
msgstr "Fehlt ein Zeilenumbruch? (Eintrag: %s)"
|
||||||
|
|
||||||
#: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067
|
#: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067
|
||||||
|
#: parser_yacc.y:1145 parser_yacc.y:1155
|
||||||
msgid "Invalid network entry."
|
msgid "Invalid network entry."
|
||||||
msgstr "Ungültiger Netzwerkeintrag."
|
msgstr "Ungültiger Netzwerkeintrag."
|
||||||
|
|
||||||
#: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254
|
#: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Invalid capability %s."
|
msgid "Invalid capability %s."
|
||||||
msgstr "Ungültige Fähigkeit %s."
|
msgstr "Ungültige Fähigkeit %s."
|
||||||
|
|
||||||
#: parser_yacc.y:1066 parser_yacc.y:1269
|
#: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "AppArmor parser error for %s%s%s at line %d: %s\n"
|
msgid "AppArmor parser error for %s%s%s at line %d: %s\n"
|
||||||
msgstr "AppArmor-Analysefehler für %s%s%s in Zeile %d: %s\n"
|
msgstr "AppArmor-Analysefehler für %s%s%s in Zeile %d: %s\n"
|
||||||
|
|
||||||
#: parser_yacc.y:1072 parser_yacc.y:1275
|
#: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "AppArmor parser error,%s%s line %d: %s\n"
|
msgid "AppArmor parser error,%s%s line %d: %s\n"
|
||||||
msgstr "AppArmor-Analysefehler,%s%s Zeile %d: %s\n"
|
msgstr "AppArmor-Analysefehler,%s%s Zeile %d: %s\n"
|
||||||
@@ -516,13 +540,13 @@ msgid "%s: Illegal open {, nesting groupings not allowed\n"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"%s: Öffnen mit { ungültig, verschachtelte Gruppierungen sind nicht zulässig\n"
|
"%s: Öffnen mit { ungültig, verschachtelte Gruppierungen sind nicht zulässig\n"
|
||||||
|
|
||||||
#: ../parser_regex.c:265 ../parser_regex.c:274
|
#: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Regex grouping error: Invalid number of items between {}\n"
|
msgid "%s: Regex grouping error: Invalid number of items between {}\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"%s: Regex-Gruppierungsfehler: Ungültige Anzahl an Einträgen zwischen {}\n"
|
"%s: Regex-Gruppierungsfehler: Ungültige Anzahl an Einträgen zwischen {}\n"
|
||||||
|
|
||||||
#: ../parser_regex.c:271 ../parser_regex.c:280
|
#: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%s: Regex grouping error: Invalid close }, no matching open { detected\n"
|
"%s: Regex grouping error: Invalid close }, no matching open { detected\n"
|
||||||
@@ -530,7 +554,7 @@ msgstr ""
|
|||||||
"%s: Regex-Gruppierungsfehler: Ungültiges schließendes Zeichen }, kein "
|
"%s: Regex-Gruppierungsfehler: Ungültiges schließendes Zeichen }, kein "
|
||||||
"passendes öffnendes Zeichen { gefunden\n"
|
"passendes öffnendes Zeichen { gefunden\n"
|
||||||
|
|
||||||
#: ../parser_regex.c:337 ../parser_regex.c:343
|
#: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%s: Regex grouping error: Unclosed grouping or character class, expecting "
|
"%s: Regex grouping error: Unclosed grouping or character class, expecting "
|
||||||
@@ -544,17 +568,17 @@ msgstr ""
|
|||||||
msgid "%s: Internal buffer overflow detected, %d characters exceeded\n"
|
msgid "%s: Internal buffer overflow detected, %d characters exceeded\n"
|
||||||
msgstr "%s: Interner Pufferüberlauf erkannt, %d Zeichen überschritten\n"
|
msgstr "%s: Interner Pufferüberlauf erkannt, %d Zeichen überschritten\n"
|
||||||
|
|
||||||
#: ../parser_regex.c:355 ../parser_regex.c:361
|
#: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Unable to parse input line '%s'\n"
|
msgid "%s: Unable to parse input line '%s'\n"
|
||||||
msgstr "%s: Eingabezeile »%s« kann nicht analysiert werden\n"
|
msgstr "%s: Eingabezeile »%s« kann nicht analysiert werden\n"
|
||||||
|
|
||||||
#: ../parser_regex.c:397 ../parser_regex.c:405
|
#: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Invalid profile name '%s' - bad regular expression\n"
|
msgid "%s: Invalid profile name '%s' - bad regular expression\n"
|
||||||
msgstr "%s: Ungültiger Profilname »%s« – Fehlerhafter regulärer Ausdruck\n"
|
msgstr "%s: Ungültiger Profilname »%s« – Fehlerhafter regulärer Ausdruck\n"
|
||||||
|
|
||||||
#: ../parser_policy.c:202 ../parser_policy.c:402
|
#: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "ERROR merging rules for profile %s, failed to load\n"
|
msgid "ERROR merging rules for profile %s, failed to load\n"
|
||||||
msgstr "FEHLER Vereinigungsregeln für Profil »%s«, Laden gescheitert\n"
|
msgstr "FEHLER Vereinigungsregeln für Profil »%s«, Laden gescheitert\n"
|
||||||
@@ -572,18 +596,18 @@ msgstr ""
|
|||||||
"erlaubt.\n"
|
"erlaubt.\n"
|
||||||
"\t»**« kann am Ende einer Regel verwendet werden.\n"
|
"\t»**« kann am Ende einer Regel verwendet werden.\n"
|
||||||
|
|
||||||
#: ../parser_policy.c:279 ../parser_policy.c:359
|
#: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "ERROR processing regexs for profile %s, failed to load\n"
|
msgid "ERROR processing regexs for profile %s, failed to load\n"
|
||||||
msgstr "FEHLER Verarbeitung der Regexs für Profil »%s«, Laden gescheitert\n"
|
msgstr "FEHLER Verarbeitung der Regexs für Profil »%s«, Laden gescheitert\n"
|
||||||
|
|
||||||
#: ../parser_policy.c:306 ../parser_policy.c:389
|
#: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "ERROR expanding variables for profile %s, failed to load\n"
|
msgid "ERROR expanding variables for profile %s, failed to load\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"FEHLER beim Erweitern der Variablen für Profil »%s«, Laden gescheitert\n"
|
"FEHLER beim Erweitern der Variablen für Profil »%s«, Laden gescheitert\n"
|
||||||
|
|
||||||
#: ../parser_policy.c:390 ../parser_policy.c:382
|
#: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "ERROR adding hat access rule for profile %s\n"
|
msgid "ERROR adding hat access rule for profile %s\n"
|
||||||
msgstr "FEHLER Hinzufügen von »hat«-Zugriffsregel für Profil %s\n"
|
msgstr "FEHLER Hinzufügen von »hat«-Zugriffsregel für Profil %s\n"
|
||||||
@@ -617,31 +641,32 @@ msgstr ""
|
|||||||
"%s: Beim Kombinieren von Regeln in der Nachverarbeitung sind Fehler "
|
"%s: Beim Kombinieren von Regeln in der Nachverarbeitung sind Fehler "
|
||||||
"aufgetreten. Der Vorgang wird abgebrochen.\n"
|
"aufgetreten. Der Vorgang wird abgebrochen.\n"
|
||||||
|
|
||||||
#: parser_lex.l:180
|
#: parser_lex.l:180 parser_lex.l:186
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Could not process include directory '%s' in '%s'"
|
msgid "Could not process include directory '%s' in '%s'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Das enthaltene Verzeichnis »%s« in »%s« kann nicht verarbeitet werden"
|
"Das enthaltene Verzeichnis »%s« in »%s« kann nicht verarbeitet werden"
|
||||||
|
|
||||||
#: ../parser_main.c:660
|
#: ../parser_main.c:660 ../parser_main.c:523
|
||||||
msgid "Feature buffer full."
|
msgid "Feature buffer full."
|
||||||
msgstr "Funktionspuffer ist voll."
|
msgstr "Funktionspuffer ist voll."
|
||||||
|
|
||||||
#: ../parser_main.c:1115 ../parser_main.c:1132
|
#: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024
|
||||||
|
#: ../parser_main.c:1041
|
||||||
msgid "Out of memory"
|
msgid "Out of memory"
|
||||||
msgstr "Nicht genug Speicher"
|
msgstr "Nicht genügend Speicher!"
|
||||||
|
|
||||||
#: ../parser_main.c:1182
|
#: ../parser_main.c:1182 ../parser_main.c:1091
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't create cache directory: %s\n"
|
msgid "Can't create cache directory: %s\n"
|
||||||
msgstr "Pufferverzeichnis kann nicht erstellt werden: %s\n"
|
msgstr "Pufferverzeichnis kann nicht erstellt werden: %s\n"
|
||||||
|
|
||||||
#: ../parser_main.c:1185
|
#: ../parser_main.c:1185 ../parser_main.c:1094
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "File in cache directory location: %s\n"
|
msgid "File in cache directory location: %s\n"
|
||||||
msgstr "Datei im Pufferverzeichnisort: %s\n"
|
msgstr "Datei im Pufferverzeichnisort: %s\n"
|
||||||
|
|
||||||
#: ../parser_main.c:1188
|
#: ../parser_main.c:1188 ../parser_main.c:1097
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't update cache directory: %s\n"
|
msgid "Can't update cache directory: %s\n"
|
||||||
msgstr "Pufferverzeichnis kann nicht aktualisiert werden: %s\n"
|
msgstr "Pufferverzeichnis kann nicht aktualisiert werden: %s\n"
|
||||||
@@ -656,11 +681,11 @@ msgstr "Intern: Unerwartetes D-Bus-Moduszeichen »%c« in der Eingabe"
|
|||||||
msgid "Internal error generated invalid DBus perm 0x%x\n"
|
msgid "Internal error generated invalid DBus perm 0x%x\n"
|
||||||
msgstr "Interner Fehler hat ungültige D-Bus-Zugriffsrechte 0x%x erstellt\n"
|
msgstr "Interner Fehler hat ungültige D-Bus-Zugriffsrechte 0x%x erstellt\n"
|
||||||
|
|
||||||
#: parser_yacc.y:575
|
#: parser_yacc.y:575 parser_yacc.y:621
|
||||||
msgid "deny prefix not allowed"
|
msgid "deny prefix not allowed"
|
||||||
msgstr "Verweigernpräfix nicht erlaubt"
|
msgstr "Verweigernpräfix nicht erlaubt"
|
||||||
|
|
||||||
#: parser_yacc.y:612
|
#: parser_yacc.y:612 parser_yacc.y:658
|
||||||
msgid "owner prefix not allowed"
|
msgid "owner prefix not allowed"
|
||||||
msgstr "Eigentümerpräfix nicht erlaubt"
|
msgstr "Eigentümerpräfix nicht erlaubt"
|
||||||
|
|
||||||
@@ -676,25 +701,25 @@ msgstr "Eigentümerpräfix nicht bei D-Bus-Regeln erlauben"
|
|||||||
msgid "owner prefix not allow on capability rules"
|
msgid "owner prefix not allow on capability rules"
|
||||||
msgstr "Eigentümerpräfix nicht bei Fähigkeitsregeln erlauben"
|
msgstr "Eigentümerpräfix nicht bei Fähigkeitsregeln erlauben"
|
||||||
|
|
||||||
#: parser_yacc.y:1357
|
#: parser_yacc.y:1357 parser_yacc.y:1613
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "invalid mount conditional %s%s"
|
msgid "invalid mount conditional %s%s"
|
||||||
msgstr "Ungültige Einhängebedingung %s%s"
|
msgstr "Ungültige Einhängebedingung %s%s"
|
||||||
|
|
||||||
#: parser_yacc.y:1374
|
#: parser_yacc.y:1374 parser_yacc.y:1628
|
||||||
msgid "bad mount rule"
|
msgid "bad mount rule"
|
||||||
msgstr "Ungültige Einhängeregel"
|
msgstr "Ungültige Einhängeregel"
|
||||||
|
|
||||||
#: parser_yacc.y:1381
|
#: parser_yacc.y:1381 parser_yacc.y:1635
|
||||||
msgid "mount point conditions not currently supported"
|
msgid "mount point conditions not currently supported"
|
||||||
msgstr "Einhängepunktbedingungen werden derzeit nicht unterstützt"
|
msgstr "Einhängepunktbedingungen werden derzeit nicht unterstützt"
|
||||||
|
|
||||||
#: parser_yacc.y:1398
|
#: parser_yacc.y:1398 parser_yacc.y:1650
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "invalid pivotroot conditional '%s'"
|
msgid "invalid pivotroot conditional '%s'"
|
||||||
msgstr "Ungültige pivotroot-Bedingung »%s«"
|
msgstr "Ungültige pivotroot-Bedingung »%s«"
|
||||||
|
|
||||||
#: ../parser_regex.c:241
|
#: ../parser_regex.c:241 ../parser_regex.c:236
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%s: Regex grouping error: Invalid close ], no matching open [ detected\n"
|
"%s: Regex grouping error: Invalid close ], no matching open [ detected\n"
|
||||||
@@ -702,20 +727,20 @@ msgstr ""
|
|||||||
"%s: Regex-Gruppierungsfehler: Ungültiges schließendes Zeichen ], kein "
|
"%s: Regex-Gruppierungsfehler: Ungültiges schließendes Zeichen ], kein "
|
||||||
"passendes öffnendes Zeichen [ gefunden\n"
|
"passendes öffnendes Zeichen [ gefunden\n"
|
||||||
|
|
||||||
#: ../parser_regex.c:257
|
#: ../parser_regex.c:257 ../parser_regex.c:256
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n"
|
msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"%s: Regex-Gruppierungsfehler: maximale Verschachtelung von {} überschritten\n"
|
"%s: Regex-Gruppierungsfehler: maximale Verschachtelung von {} überschritten\n"
|
||||||
|
|
||||||
#: ../parser_policy.c:366
|
#: ../parser_policy.c:366 ../parser_policy.c:339
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "ERROR processing policydb rules for profile %s, failed to load\n"
|
msgid "ERROR processing policydb rules for profile %s, failed to load\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"FEHLER beim Verarbeiten der policydb-Regeln für das Profil %s. Das Laden ist "
|
"FEHLER beim Verarbeiten der policydb-Regeln für das Profil %s. Das Laden ist "
|
||||||
"fehlgeschlagen.\n"
|
"fehlgeschlagen.\n"
|
||||||
|
|
||||||
#: ../parser_policy.c:396
|
#: ../parser_policy.c:396 ../parser_policy.c:369
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "ERROR replacing aliases for profile %s, failed to load\n"
|
msgid "ERROR replacing aliases for profile %s, failed to load\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@@ -95,13 +95,15 @@ void update_mru_tstamp(FILE *file, const char *name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *cache_filename(const char *cachedir, const char *basename)
|
char *cache_filename(aa_policy_cache *pc, int dir, const char *basename)
|
||||||
{
|
{
|
||||||
char *cachename;
|
char *cachename;
|
||||||
|
autofree char *path;
|
||||||
|
|
||||||
if (asprintf(&cachename, "%s/%s", cachedir, basename) < 0) {
|
path = aa_policy_cache_dir_path(pc, dir);
|
||||||
|
if (!path || asprintf(&cachename, "%s/%s", path, basename) < 0) {
|
||||||
PERROR("Memory allocation error.");
|
PERROR("Memory allocation error.");
|
||||||
exit(1);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cachename;
|
return cachename;
|
||||||
@@ -147,13 +149,13 @@ int setup_cache_tmp(const char **cachetmpname, const char *cachename)
|
|||||||
*cachetmpname = NULL;
|
*cachetmpname = NULL;
|
||||||
if (write_cache) {
|
if (write_cache) {
|
||||||
/* Otherwise, set up to save a cached copy */
|
/* Otherwise, set up to save a cached copy */
|
||||||
if (asprintf(&tmpname, "%s-XXXXXX", cachename)<0) {
|
if (asprintf(&tmpname, "%s-XXXXXX", cachename) < 0) {
|
||||||
perror("asprintf");
|
perror("asprintf");
|
||||||
exit(1);
|
return -1;
|
||||||
}
|
}
|
||||||
if ((cache_fd = mkstemp(tmpname)) < 0) {
|
if ((cache_fd = mkstemp(tmpname)) < 0) {
|
||||||
perror("mkstemp");
|
perror("mkstemp");
|
||||||
exit(1);
|
return -1;
|
||||||
}
|
}
|
||||||
*cachetmpname = tmpname;
|
*cachetmpname = tmpname;
|
||||||
}
|
}
|
||||||
|
@@ -41,7 +41,7 @@ extern int debug_cache;
|
|||||||
void set_cache_tstamp(struct timespec t);
|
void set_cache_tstamp(struct timespec t);
|
||||||
void update_mru_tstamp(FILE *file, const char *path);
|
void update_mru_tstamp(FILE *file, const char *path);
|
||||||
bool valid_cached_file_version(const char *cachename);
|
bool valid_cached_file_version(const char *cachename);
|
||||||
char *cache_filename(const char *cachedir, const char *basename);
|
char *cache_filename(aa_policy_cache *pc, int dir, const char *basename);
|
||||||
void valid_read_cache(const char *cachename);
|
void valid_read_cache(const char *cachename);
|
||||||
int cache_hit(const char *cachename);
|
int cache_hit(const char *cachename);
|
||||||
int setup_cache_tmp(const char **cachetmpname, const char *cachename);
|
int setup_cache_tmp(const char **cachetmpname, const char *cachename);
|
||||||
|
@@ -117,11 +117,14 @@ skip_profile() {
|
|||||||
"${profile%\~}" != "${profile}" ] ; then
|
"${profile%\~}" != "${profile}" ] ; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
# Silently ignore the dpkg files
|
# Silently ignore the dpkg and pacman files
|
||||||
if [ "${profile%.dpkg-new}" != "${profile}" -o \
|
if [ "${profile%.dpkg-new}" != "${profile}" -o \
|
||||||
"${profile%.dpkg-old}" != "${profile}" -o \
|
"${profile%.dpkg-old}" != "${profile}" -o \
|
||||||
"${profile%.dpkg-dist}" != "${profile}" -o \
|
"${profile%.dpkg-dist}" != "${profile}" -o \
|
||||||
"${profile%.dpkg-bak}" != "${profile}" ] ; then
|
"${profile%.dpkg-bak}" != "${profile}" -o \
|
||||||
|
"${profile%.dpkg-remove}" != "${profile}" -o \
|
||||||
|
"${profile%.pacsave}" != "${profile}" -o \
|
||||||
|
"${profile%.pacnew}" != "${profile}" ] ; then
|
||||||
return 2
|
return 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@@ -1,149 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
|
||||||
# NOVELL (All rights reserved)
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of version 2 of the GNU General Public
|
|
||||||
# License 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, contact Novell, Inc.
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# rc.apparmor by Steve Beattie
|
|
||||||
#
|
|
||||||
# /etc/init.d/boot.apparmor
|
|
||||||
# and its symbolic link
|
|
||||||
# /sbin/rcapparmor
|
|
||||||
#
|
|
||||||
# chkconfig: 2345 01 99
|
|
||||||
# description: AppArmor rc file. This rc script inserts the apparmor \
|
|
||||||
# module and runs the parser on the /etc/apparmor.d/ \
|
|
||||||
# directory.
|
|
||||||
#
|
|
||||||
### BEGIN INIT INFO
|
|
||||||
# Provides: apparmor
|
|
||||||
# Required-Start: boot.cleanup
|
|
||||||
# Required-Stop: $null
|
|
||||||
# Should-Start: $local_fs
|
|
||||||
# Should-Stop: $null
|
|
||||||
# Default-Start: B
|
|
||||||
# Default-Stop:
|
|
||||||
# Short-Description: AppArmor initialization
|
|
||||||
# Description: AppArmor rc file. This rc script inserts the apparmor
|
|
||||||
# module and runs the parser on the /etc/apparmor.d/
|
|
||||||
# directory.
|
|
||||||
### END INIT INFO
|
|
||||||
APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions
|
|
||||||
|
|
||||||
# source function library
|
|
||||||
if [ -f /etc/init.d/functions ]; then
|
|
||||||
. /etc/init.d/functions
|
|
||||||
elif [ -f /etc/rc.d/init.d/functions ]; then
|
|
||||||
. /etc/rc.d/init.d/functions
|
|
||||||
elif [ -f /lib/lsb/init-functions ]; then
|
|
||||||
. /lib/lsb/init-functions
|
|
||||||
else
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ugh, SUSE doesn't implement action
|
|
||||||
aa_action() { STRING=$1
|
|
||||||
shift
|
|
||||||
"$@"
|
|
||||||
rc=$?
|
|
||||||
if [ $rc -eq 0 ] ; then
|
|
||||||
log_success_msg $"$STRING "
|
|
||||||
else
|
|
||||||
log_failure_msg $"$STRING "
|
|
||||||
fi
|
|
||||||
return $rc
|
|
||||||
}
|
|
||||||
|
|
||||||
aa_log_success_msg() {
|
|
||||||
log_success_msg $*
|
|
||||||
}
|
|
||||||
|
|
||||||
aa_log_warning_msg() {
|
|
||||||
log_warning_msg $*
|
|
||||||
}
|
|
||||||
|
|
||||||
aa_log_failure_msg() {
|
|
||||||
log_failure_msg '\n'$*
|
|
||||||
}
|
|
||||||
|
|
||||||
aa_log_action_start() {
|
|
||||||
echo -n
|
|
||||||
}
|
|
||||||
|
|
||||||
aa_log_action_end() {
|
|
||||||
echo -n
|
|
||||||
}
|
|
||||||
|
|
||||||
aa_log_daemon_msg() {
|
|
||||||
echo -en "$@ "
|
|
||||||
}
|
|
||||||
|
|
||||||
aa_log_skipped_msg() {
|
|
||||||
echo -en "$@"
|
|
||||||
echo -e "$rc_skipped"
|
|
||||||
}
|
|
||||||
|
|
||||||
_set_status() {
|
|
||||||
return $1
|
|
||||||
}
|
|
||||||
|
|
||||||
aa_log_end_msg() {
|
|
||||||
_set_status $1
|
|
||||||
rc_status -v
|
|
||||||
}
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
echo "Usage: $0 {start|stop|restart|try-restart|reload|force-reload|status|kill}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# source apparmor function library
|
|
||||||
if [ -f "${APPARMOR_FUNCTIONS}" ]; then
|
|
||||||
. ${APPARMOR_FUNCTIONS}
|
|
||||||
else
|
|
||||||
aa_log_failure_msg "Unable to find AppArmor initscript functions"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
start)
|
|
||||||
apparmor_start
|
|
||||||
rc=$?
|
|
||||||
;;
|
|
||||||
stop)
|
|
||||||
apparmor_stop
|
|
||||||
rc=$?
|
|
||||||
;;
|
|
||||||
restart|reload|force-reload)
|
|
||||||
apparmor_restart
|
|
||||||
rc=$?
|
|
||||||
;;
|
|
||||||
try-restart)
|
|
||||||
apparmor_try_restart
|
|
||||||
rc=$?
|
|
||||||
;;
|
|
||||||
kill)
|
|
||||||
apparmor_kill
|
|
||||||
rc=$?
|
|
||||||
;;
|
|
||||||
status)
|
|
||||||
apparmor_status
|
|
||||||
rc=$?
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
exit $rc
|
|
||||||
|
|
@@ -60,13 +60,6 @@ class AAParserCachingCommon(testlib.AATestTemplate):
|
|||||||
self.tmp_dir = tempfile.mkdtemp(prefix='aa-caching-')
|
self.tmp_dir = tempfile.mkdtemp(prefix='aa-caching-')
|
||||||
os.chmod(self.tmp_dir, 0o755)
|
os.chmod(self.tmp_dir, 0o755)
|
||||||
|
|
||||||
# create directory for cached blobs
|
|
||||||
self.cache_dir = os.path.join(self.tmp_dir, 'cache')
|
|
||||||
os.mkdir(self.cache_dir)
|
|
||||||
|
|
||||||
# default path of the output cache file
|
|
||||||
self.cache_file = os.path.join(self.cache_dir, PROFILE)
|
|
||||||
|
|
||||||
# write our sample abstraction and profile out
|
# write our sample abstraction and profile out
|
||||||
self.abstraction = testlib.write_file(self.tmp_dir, ABSTRACTION, ABSTRACTION_CONTENTS)
|
self.abstraction = testlib.write_file(self.tmp_dir, ABSTRACTION, ABSTRACTION_CONTENTS)
|
||||||
self.profile = testlib.write_file(self.tmp_dir, PROFILE, PROFILE_CONTENTS)
|
self.profile = testlib.write_file(self.tmp_dir, PROFILE, PROFILE_CONTENTS)
|
||||||
@@ -80,6 +73,13 @@ class AAParserCachingCommon(testlib.AATestTemplate):
|
|||||||
if not self.is_apparmorfs_mounted():
|
if not self.is_apparmorfs_mounted():
|
||||||
self.cmd_prefix += ['-M', './features_files/features.all']
|
self.cmd_prefix += ['-M', './features_files/features.all']
|
||||||
|
|
||||||
|
# create directory for cached blobs
|
||||||
|
# NOTE: get_cache_dir() requires cmd_prefix to be fully initialized
|
||||||
|
self.cache_dir = self.get_cache_dir(create=True)
|
||||||
|
|
||||||
|
# default path of the output cache file
|
||||||
|
self.cache_file = os.path.join(self.cache_dir, PROFILE)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
'''teardown for each test'''
|
'''teardown for each test'''
|
||||||
|
|
||||||
@@ -89,6 +89,22 @@ class AAParserCachingCommon(testlib.AATestTemplate):
|
|||||||
if os.path.exists(self.tmp_dir):
|
if os.path.exists(self.tmp_dir):
|
||||||
shutil.rmtree(self.tmp_dir)
|
shutil.rmtree(self.tmp_dir)
|
||||||
|
|
||||||
|
def get_cache_dir(self, create=False):
|
||||||
|
cmd = [config.parser, '--print-cache-dir'] + self.cmd_prefix
|
||||||
|
rc, report = self.run_cmd(cmd)
|
||||||
|
if rc != 0:
|
||||||
|
if "unrecognized option '--print-cache-dir'" not in report:
|
||||||
|
self.fail('Unknown apparmor_parser error:\n%s' % report)
|
||||||
|
|
||||||
|
cache_dir = os.path.join(self.tmp_dir, 'cache')
|
||||||
|
else:
|
||||||
|
cache_dir = report.strip()
|
||||||
|
|
||||||
|
if create:
|
||||||
|
os.makedirs(cache_dir)
|
||||||
|
|
||||||
|
return cache_dir
|
||||||
|
|
||||||
def assert_path_exists(self, path, expected=True):
|
def assert_path_exists(self, path, expected=True):
|
||||||
if expected is True:
|
if expected is True:
|
||||||
self.assertTrue(os.path.exists(path),
|
self.assertTrue(os.path.exists(path),
|
||||||
@@ -178,16 +194,16 @@ class AAParserAltCacheBasicTests(AAParserBasicCachingTests):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(AAParserAltCacheBasicTests, self).setUp()
|
super(AAParserAltCacheBasicTests, self).setUp()
|
||||||
|
|
||||||
alt_cache_dir = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
|
alt_cache_loc = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
|
||||||
os.chmod(alt_cache_dir, 0o755)
|
os.chmod(alt_cache_loc, 0o755)
|
||||||
|
|
||||||
self.unused_cache_dir = self.cache_dir
|
self.unused_cache_loc = self.cache_dir
|
||||||
self.cache_dir = alt_cache_dir
|
self.cmd_prefix.extend(['--cache-loc', alt_cache_loc])
|
||||||
self.cmd_prefix.extend(['--cache-loc', alt_cache_dir])
|
self.cache_dir = self.get_cache_dir()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
if len(os.listdir(self.unused_cache_dir)) > 0:
|
if len(os.listdir(self.unused_cache_loc)) > 0:
|
||||||
self.fail('original cache dir \'%s\' not empty' % self.unused_cache_dir)
|
self.fail('original cache dir \'%s\' not empty' % self.unused_cache_loc)
|
||||||
super(AAParserAltCacheBasicTests, self).tearDown()
|
super(AAParserAltCacheBasicTests, self).tearDown()
|
||||||
|
|
||||||
|
|
||||||
@@ -314,18 +330,22 @@ class AAParserCachingTests(AAParserCachingCommon):
|
|||||||
self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
|
self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
|
||||||
self.assert_path_exists(self.cache_file, expected=False)
|
self.assert_path_exists(self.cache_file, expected=False)
|
||||||
|
|
||||||
def test_cache_writing_updates_features(self):
|
def test_cache_writing_collision_of_features(self):
|
||||||
'''test cache writing updates features'''
|
'''test cache writing collision of features'''
|
||||||
|
# cache dir with different features causes a collision resulting
|
||||||
|
# in a new cache dir
|
||||||
self.require_apparmorfs()
|
self.require_apparmorfs()
|
||||||
|
|
||||||
features_file = testlib.write_file(self.cache_dir, '.features', 'monkey\n')
|
features_file = testlib.write_file(self.cache_dir, '.features', 'monkey\n')
|
||||||
|
new_file = self.get_cache_dir()
|
||||||
|
new_features_file = new_file + '/.features';
|
||||||
|
|
||||||
cmd = list(self.cmd_prefix)
|
cmd = list(self.cmd_prefix)
|
||||||
cmd.extend(['-v', '--write-cache', '-r', self.profile])
|
cmd.extend(['-v', '--write-cache', '-r', self.profile])
|
||||||
self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
|
self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
|
||||||
self.assert_path_exists(features_file)
|
self.assert_path_exists(features_file)
|
||||||
self.compare_features_file(features_file)
|
self.assert_path_exists(new_features_file)
|
||||||
|
self.compare_features_file(new_features_file)
|
||||||
|
|
||||||
def test_cache_writing_updates_cache_file(self):
|
def test_cache_writing_updates_cache_file(self):
|
||||||
'''test cache writing updates cache file'''
|
'''test cache writing updates cache file'''
|
||||||
@@ -494,13 +514,13 @@ class AAParserAltCacheTests(AAParserCachingTests):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(AAParserAltCacheTests, self).setUp()
|
super(AAParserAltCacheTests, self).setUp()
|
||||||
|
|
||||||
alt_cache_dir = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
|
alt_cache_loc = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
|
||||||
os.chmod(alt_cache_dir, 0o755)
|
os.chmod(alt_cache_loc, 0o755)
|
||||||
|
|
||||||
self.orig_cache_dir = self.cache_dir
|
self.orig_cache_dir = self.cache_dir
|
||||||
self.cache_dir = alt_cache_dir
|
self.cmd_prefix.extend(['--cache-loc', alt_cache_loc])
|
||||||
|
self.cache_dir = self.get_cache_dir(create=True)
|
||||||
self.cache_file = os.path.join(self.cache_dir, PROFILE)
|
self.cache_file = os.path.join(self.cache_dir, PROFILE)
|
||||||
self.cmd_prefix.extend(['--cache-loc', alt_cache_dir])
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
if self.check_orig_cache and len(os.listdir(self.orig_cache_dir)) > 0:
|
if self.check_orig_cache and len(os.listdir(self.orig_cache_dir)) > 0:
|
||||||
|
7
parser/tst/simple_tests/bare_include_tests/bad_11.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/bad_11.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - non-existent include should fail
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "does-not-exist/does-not-exist"
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/bad_12.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/bad_12.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - mis-parsing include should fail
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "/does-not-exist/does-not-exist"
|
||||||
|
}
|
8
parser/tst/simple_tests/bare_include_tests/bad_13.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/bad_13.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - non-existent include should fail
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "does-not-exist/does-not-exist"
|
||||||
|
#include <includes/base>
|
||||||
|
}
|
8
parser/tst/simple_tests/bare_include_tests/bad_14.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/bad_14.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - non-existent include should fail
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include <includes/base>
|
||||||
|
#include "../does-not-exist/does-not-exist"
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_11.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_11.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include "simple_tests/include_tests/includes_okay_helper.include"
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_12.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_12.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include "../tst/simple_tests/include_tests/includes_okay_helper.include"
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_13.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_13.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include "./simple_tests/include_tests/includes_okay_helper.include"
|
||||||
|
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_14.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_14.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - test some "odd" locations of includes
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
/does/not/exist mr, include <includes/base> /bin/true Px,
|
||||||
|
include "../tst/simple_tests/include_tests/includes_okay_helper.include" include <includes/base>
|
||||||
|
}
|
9
parser/tst/simple_tests/bare_include_tests/ok_15.sd
Normal file
9
parser/tst/simple_tests/bare_include_tests/ok_15.sd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of a directory
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include <includes/base>
|
||||||
|
include "simple_tests/includes/"
|
||||||
|
include <includes/base>
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_16.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_16.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include simple_tests/include_tests/includes_okay_helper.include
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_17.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_17.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include ../tst/simple_tests/include_tests/includes_okay_helper.include
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_18.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_18.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include ./simple_tests/include_tests/includes_okay_helper.include
|
||||||
|
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_19.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_19.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - test some "odd" locations of includes
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
/does/not/exist mr, include <includes/base> /bin/true Px,
|
||||||
|
include ../tst/simple_tests/include_tests/includes_okay_helper.include include <includes/base>
|
||||||
|
}
|
9
parser/tst/simple_tests/bare_include_tests/ok_20.sd
Normal file
9
parser/tst/simple_tests/bare_include_tests/ok_20.sd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of a directory
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include <includes/base>
|
||||||
|
include simple_tests/includes/
|
||||||
|
include <includes/base>
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_26.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_26.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include "simple_tests/include_tests/includes with space helper.include"
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_27.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_27.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include "simple_tests/include_tests/includes with space helper.include" #comment
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_28.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_28.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include <"include_tests/includes with space helper.include">
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_29.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_29.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include <"include_tests/includes with space helper.include"> #comment
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_30.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_30.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include <include_tests/includes with space helper.include>
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_31.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_31.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include <include_tests/includes with space helper.include> #comment
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_61.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_61.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists "simple_tests/include_tests/includes_okay_helper.include"
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_62.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_62.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists "../tst/simple_tests/include_tests/includes_okay_helper.include"
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_63.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_63.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists "./simple_tests/include_tests/includes_okay_helper.include"
|
||||||
|
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_64.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_64.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - test some "odd" locations of include if existss
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
/does/not/exist mr, include if exists <includes/base> /bin/true Px,
|
||||||
|
include if exists "../tst/simple_tests/include_tests/includes_okay_helper.include" include if exists <includes/base>
|
||||||
|
}
|
9
parser/tst/simple_tests/bare_include_tests/ok_65.sd
Normal file
9
parser/tst/simple_tests/bare_include_tests/ok_65.sd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of a directory
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists <includes/base>
|
||||||
|
include if exists "simple_tests/includes/"
|
||||||
|
include if exists <includes/base>
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_66.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_66.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists simple_tests/include_tests/includes_okay_helper.include
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_67.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_67.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists ../tst/simple_tests/include_tests/includes_okay_helper.include
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_68.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_68.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists ./simple_tests/include_tests/includes_okay_helper.include
|
||||||
|
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_69.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_69.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - test some "odd" locations of include if existss
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
/does/not/exist mr, include if exists <includes/base> /bin/true Px,
|
||||||
|
include if exists ../tst/simple_tests/include_tests/includes_okay_helper.include include if exists <includes/base>
|
||||||
|
}
|
9
parser/tst/simple_tests/bare_include_tests/ok_70.sd
Normal file
9
parser/tst/simple_tests/bare_include_tests/ok_70.sd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of a directory
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists <includes/base>
|
||||||
|
include if exists simple_tests/includes/
|
||||||
|
include if exists <includes/base>
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_76.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_76.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists "simple_tests/include_tests/includes with space helper.include"
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_77.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_77.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists "simple_tests/include_tests/includes with space helper.include" #comment
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_78.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_78.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists <"include_tests/includes with space helper.include">
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_79.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_79.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists <"include_tests/includes with space helper.include"> #comment
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_80.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_80.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists <include_tests/includes with space helper.include>
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_81.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_81.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists <include_tests/includes with space helper.include> #comment
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_82.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_82.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if exist testing - non-existent include should pass
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists "does-not-exist/does-not-exist"
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_83.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_83.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if exists testing - abs path include does not exist should pass
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists "/does-not-exist/does-not-exist"
|
||||||
|
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_84.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_84.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if exists testing - non-existent include should pass
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include <includes/base>
|
||||||
|
include if exists "../does-not-exist/does-not-exist"
|
||||||
|
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_85.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_85.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if exists testing - non-existent include should pass
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include <includes/base>
|
||||||
|
include if exists "../does-not-exist/does-not-exist"
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_86.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_86.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if exists testing - non-existent include should pass
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists "does-not-exist/does-not-exist"
|
||||||
|
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_87.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_87.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if exists testing - non-existent include should pass
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists <does-not-exist/does-not-exist>
|
||||||
|
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_88.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_88.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION include if exists testing - non-existent include should pass
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
include if exists <does-not-exist/does-not-exist>
|
||||||
|
include <includes/base>
|
||||||
|
}
|
7
parser/tst/simple_tests/include_tests/bad_11.sd
Normal file
7
parser/tst/simple_tests/include_tests/bad_11.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - non-existent include should fail
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "does-not-exist/does-not-exist"
|
||||||
|
}
|
7
parser/tst/simple_tests/include_tests/bad_12.sd
Normal file
7
parser/tst/simple_tests/include_tests/bad_12.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - mis-parsing include should fail
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "/does-not-exist/does-not-exist"
|
||||||
|
}
|
8
parser/tst/simple_tests/include_tests/bad_13.sd
Normal file
8
parser/tst/simple_tests/include_tests/bad_13.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - non-existent include should fail
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "does-not-exist/does-not-exist"
|
||||||
|
#include <includes/base>
|
||||||
|
}
|
8
parser/tst/simple_tests/include_tests/bad_14.sd
Normal file
8
parser/tst/simple_tests/include_tests/bad_14.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - non-existent include should fail
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include <includes/base>
|
||||||
|
#include "../does-not-exist/does-not-exist"
|
||||||
|
}
|
7
parser/tst/simple_tests/include_tests/bad_15.sd
Normal file
7
parser/tst/simple_tests/include_tests/bad_15.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - non-existent include should fail
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "does-not-exist/does-not-exist"
|
||||||
|
}
|
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION A helper for includes_okay.sd
|
||||||
|
#
|
||||||
|
#include <includes/fonts>
|
||||||
|
|
||||||
|
/tmp/** r,
|
7
parser/tst/simple_tests/include_tests/ok_11.sd
Normal file
7
parser/tst/simple_tests/include_tests/ok_11.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "simple_tests/include_tests/includes_okay_helper.include"
|
||||||
|
}
|
7
parser/tst/simple_tests/include_tests/ok_12.sd
Normal file
7
parser/tst/simple_tests/include_tests/ok_12.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "../tst/simple_tests/include_tests/includes_okay_helper.include"
|
||||||
|
}
|
7
parser/tst/simple_tests/include_tests/ok_13.sd
Normal file
7
parser/tst/simple_tests/include_tests/ok_13.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "./simple_tests/include_tests/includes_okay_helper.include"
|
||||||
|
}
|
8
parser/tst/simple_tests/include_tests/ok_14.sd
Normal file
8
parser/tst/simple_tests/include_tests/ok_14.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - test some "odd" locations of includes
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
/does/not/exist mr, #include <includes/base> /bin/true Px,
|
||||||
|
#include "../tst/simple_tests/include_tests/includes_okay_helper.include" #include <includes/base>
|
||||||
|
}
|
9
parser/tst/simple_tests/include_tests/ok_15.sd
Normal file
9
parser/tst/simple_tests/include_tests/ok_15.sd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of a directory
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include <includes/base>
|
||||||
|
#include "simple_tests/includes/"
|
||||||
|
#include <includes/base>
|
||||||
|
}
|
7
parser/tst/simple_tests/include_tests/ok_16.sd
Normal file
7
parser/tst/simple_tests/include_tests/ok_16.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include simple_tests/include_tests/includes_okay_helper.include
|
||||||
|
}
|
7
parser/tst/simple_tests/include_tests/ok_17.sd
Normal file
7
parser/tst/simple_tests/include_tests/ok_17.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include ../tst/simple_tests/include_tests/includes_okay_helper.include
|
||||||
|
}
|
7
parser/tst/simple_tests/include_tests/ok_18.sd
Normal file
7
parser/tst/simple_tests/include_tests/ok_18.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include ./simple_tests/include_tests/includes_okay_helper.include
|
||||||
|
}
|
8
parser/tst/simple_tests/include_tests/ok_19.sd
Normal file
8
parser/tst/simple_tests/include_tests/ok_19.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - test some "odd" locations of includes
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
/does/not/exist mr, #include <includes/base> /bin/true Px,
|
||||||
|
#include ../tst/simple_tests/include_tests/includes_okay_helper.include #include <includes/base>
|
||||||
|
}
|
9
parser/tst/simple_tests/include_tests/ok_20.sd
Normal file
9
parser/tst/simple_tests/include_tests/ok_20.sd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of a directory
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include <includes/base>
|
||||||
|
#include simple_tests/includes/
|
||||||
|
#include <includes/base>
|
||||||
|
}
|
7
parser/tst/simple_tests/include_tests/ok_26.sd
Normal file
7
parser/tst/simple_tests/include_tests/ok_26.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "simple_tests/include_tests/includes with space helper.include"
|
||||||
|
}
|
7
parser/tst/simple_tests/include_tests/ok_27.sd
Normal file
7
parser/tst/simple_tests/include_tests/ok_27.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION includes testing - basic include of global and local include
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/does/not/exist {
|
||||||
|
#include "simple_tests/include_tests/includes with space helper.include" #comment
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user