struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name);
struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n);
+struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n);
+struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n);
struct aa_ns *__aa_find_or_create_ns(struct aa_ns *parent, const char *name,
struct dentry *dir);
struct aa_ns *aa_prepare_ns(struct aa_ns *root, const char *name);
return __aa_findn_ns(head, name, strlen(name));
}
+static inline struct aa_ns *__aa_lookup_ns(struct aa_ns *base,
+ const char *hname)
+{
+ return __aa_lookupn_ns(base, hname, strlen(hname));
+}
+
+static inline struct aa_ns *aa_lookup_ns(struct aa_ns *view, const char *name)
+{
+ return aa_lookupn_ns(view, name, strlen(name));
+}
+
#endif /* AA_NAMESPACE_H */
name = aa_splitn_fqname(fqname, n, &ns_name, &ns_len);
if (ns_name) {
- ns = aa_findn_ns(base->ns, ns_name, ns_len);
+ ns = aa_lookupn_ns(base->ns, ns_name, ns_len);
if (!ns)
return NULL;
} else
struct aa_ns *root = NULL, *ns = NULL;
struct aa_profile *profile = NULL;
const char *name = fqname, *info = NULL;
- char *ns_name = NULL;
+ const char *ns_name = NULL;
ssize_t error = 0;
if (*fqname == 0) {
root = view;
if (fqname[0] == ':') {
- name = aa_split_fqname(fqname, &ns_name);
+ size_t ns_len;
+
+ name = aa_splitn_fqname(fqname, size, &ns_name, &ns_len);
/* released below */
- ns = aa_find_ns(root, ns_name);
+ ns = aa_lookupn_ns(root, ns_name, ns_len);
if (!ns) {
info = "namespace does not exist";
error = -ENOENT;
return aa_findn_ns(root, name, strlen(name));
}
+/**
+ * __aa_lookupn_ns - lookup the namespace matching @hname
+ * @base: base list to start looking up profile name from (NOT NULL)
+ * @hname: hierarchical ns name (NOT NULL)
+ * @n: length of @hname
+ *
+ * Requires: rcu_read_lock be held
+ *
+ * Returns: unrefcounted ns pointer or NULL if not found
+ *
+ * Do a relative name lookup, recursing through profile tree.
+ */
+struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n)
+{
+ struct aa_ns *ns = view;
+ const char *split;
+
+ for (split = strnstr(hname, "//", n); split;
+ split = strnstr(hname, "//", n)) {
+ ns = __aa_findn_ns(&ns->sub_ns, hname, split - hname);
+ if (!ns)
+ return NULL;
+
+ n -= split + 2 - hname;
+ hname = split + 2;
+ }
+
+ if (n)
+ return __aa_findn_ns(&ns->sub_ns, hname, n);
+ return NULL;
+}
+
+/**
+ * aa_lookupn_ns - look up a policy namespace relative to @view
+ * @view: namespace to search in (NOT NULL)
+ * @name: name of namespace to find (NOT NULL)
+ * @n: length of @name
+ *
+ * Returns: a refcounted namespace on the list, or NULL if no namespace
+ * called @name exists.
+ *
+ * refcount released by caller
+ */
+struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n)
+{
+ struct aa_ns *ns = NULL;
+
+ rcu_read_lock();
+ ns = aa_get_ns(__aa_lookupn_ns(view, name, n));
+ rcu_read_unlock();
+
+ return ns;
+}
+
static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
struct dentry *dir)
{