aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/services.c
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/services.c
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/services.c')
-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 40660ffd49b6..e4249adaa880 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1996,6 +1996,101 @@ out:
1996 return rc; 1996 return rc;
1997} 1997}
1998 1998
1999static int get_classes_callback(void *k, void *d, void *args)
2000{
2001 struct class_datum *datum = d;
2002 char *name = k, **classes = args;
2003 int value = datum->value - 1;
2004
2005 classes[value] = kstrdup(name, GFP_ATOMIC);
2006 if (!classes[value])
2007 return -ENOMEM;
2008
2009 return 0;
2010}
2011
2012int security_get_classes(char ***classes, int *nclasses)
2013{
2014 int rc = -ENOMEM;
2015
2016 POLICY_RDLOCK;
2017
2018 *nclasses = policydb.p_classes.nprim;
2019 *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC);
2020 if (!*classes)
2021 goto out;
2022
2023 rc = hashtab_map(policydb.p_classes.table, get_classes_callback,
2024 *classes);
2025 if (rc < 0) {
2026 int i;
2027 for (i = 0; i < *nclasses; i++)
2028 kfree((*classes)[i]);
2029 kfree(*classes);
2030 }
2031
2032out:
2033 POLICY_RDUNLOCK;
2034 return rc;
2035}
2036
2037static int get_permissions_callback(void *k, void *d, void *args)
2038{
2039 struct perm_datum *datum = d;
2040 char *name = k, **perms = args;
2041 int value = datum->value - 1;
2042
2043 perms[value] = kstrdup(name, GFP_ATOMIC);
2044 if (!perms[value])
2045 return -ENOMEM;
2046
2047 return 0;
2048}
2049
2050int security_get_permissions(char *class, char ***perms, int *nperms)
2051{
2052 int rc = -ENOMEM, i;
2053 struct class_datum *match;
2054
2055 POLICY_RDLOCK;
2056
2057 match = hashtab_search(policydb.p_classes.table, class);
2058 if (!match) {
2059 printk(KERN_ERR "%s: unrecognized class %s\n",
2060 __FUNCTION__, class);
2061 rc = -EINVAL;
2062 goto out;
2063 }
2064
2065 *nperms = match->permissions.nprim;
2066 *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC);
2067 if (!*perms)
2068 goto out;
2069
2070 if (match->comdatum) {
2071 rc = hashtab_map(match->comdatum->permissions.table,
2072 get_permissions_callback, *perms);
2073 if (rc < 0)
2074 goto err;
2075 }
2076
2077 rc = hashtab_map(match->permissions.table, get_permissions_callback,
2078 *perms);
2079 if (rc < 0)
2080 goto err;
2081
2082out:
2083 POLICY_RDUNLOCK;
2084 return rc;
2085
2086err:
2087 POLICY_RDUNLOCK;
2088 for (i = 0; i < *nperms; i++)
2089 kfree((*perms)[i]);
2090 kfree(*perms);
2091 return rc;
2092}
2093
1999struct selinux_audit_rule { 2094struct selinux_audit_rule {
2000 u32 au_seqno; 2095 u32 au_seqno;
2001 struct context au_ctxt; 2096 struct context au_ctxt;