summaryrefslogtreecommitdiffstats
path: root/security/selinux/ss
diff options
context:
space:
mode:
authorChristopher J. PeBenito <cpebenito@tresys.com>2007-05-23 09:12:06 -0400
committerJames Morris <jmorris@namei.org>2007-07-11 22:52:15 -0400
commit55fcf09b3fe4325c9395ebbb0322a547a157ebc7 (patch)
tree36415abc8ad7e917909a1fbfbdcc8ad84f0cebd2 /security/selinux/ss
parent4eb6bf6bfb580afaf1e1a1d30cba17a078530cf4 (diff)
selinux: add support for querying object classes and permissions from the running policy
Add support to the SELinux security server for obtaining a list of classes, and for obtaining a list of permissions for a specified class. Signed-off-by: Christopher J. PeBenito <cpebenito@tresys.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/ss')
-rw-r--r--security/selinux/ss/services.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 40660ffd49b..e4249adaa88 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1996,6 +1996,101 @@ out:
return rc;
}
+static int get_classes_callback(void *k, void *d, void *args)
+{
+ struct class_datum *datum = d;
+ char *name = k, **classes = args;
+ int value = datum->value - 1;
+
+ classes[value] = kstrdup(name, GFP_ATOMIC);
+ if (!classes[value])
+ return -ENOMEM;
+
+ return 0;
+}
+
+int security_get_classes(char ***classes, int *nclasses)
+{
+ int rc = -ENOMEM;
+
+ POLICY_RDLOCK;
+
+ *nclasses = policydb.p_classes.nprim;
+ *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC);
+ if (!*classes)
+ goto out;
+
+ rc = hashtab_map(policydb.p_classes.table, get_classes_callback,
+ *classes);
+ if (rc < 0) {
+ int i;
+ for (i = 0; i < *nclasses; i++)
+ kfree((*classes)[i]);
+ kfree(*classes);
+ }
+
+out:
+ POLICY_RDUNLOCK;
+ return rc;
+}
+
+static int get_permissions_callback(void *k, void *d, void *args)
+{
+ struct perm_datum *datum = d;
+ char *name = k, **perms = args;
+ int value = datum->value - 1;
+
+ perms[value] = kstrdup(name, GFP_ATOMIC);
+ if (!perms[value])
+ return -ENOMEM;
+
+ return 0;
+}
+
+int security_get_permissions(char *class, char ***perms, int *nperms)
+{
+ int rc = -ENOMEM, i;
+ struct class_datum *match;
+
+ POLICY_RDLOCK;
+
+ match = hashtab_search(policydb.p_classes.table, class);
+ if (!match) {
+ printk(KERN_ERR "%s: unrecognized class %s\n",
+ __FUNCTION__, class);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ *nperms = match->permissions.nprim;
+ *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC);
+ if (!*perms)
+ goto out;
+
+ if (match->comdatum) {
+ rc = hashtab_map(match->comdatum->permissions.table,
+ get_permissions_callback, *perms);
+ if (rc < 0)
+ goto err;
+ }
+
+ rc = hashtab_map(match->permissions.table, get_permissions_callback,
+ *perms);
+ if (rc < 0)
+ goto err;
+
+out:
+ POLICY_RDUNLOCK;
+ return rc;
+
+err:
+ POLICY_RDUNLOCK;
+ for (i = 0; i < *nperms; i++)
+ kfree((*perms)[i]);
+ kfree(*perms);
+ return rc;
+}
+
struct selinux_audit_rule {
u32 au_seqno;
struct context au_ctxt;