return data;
}
-static ssize_t policy_update(int binop, const char __user *buf, size_t size,
+static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
loff_t *pos, struct aa_ns *ns)
{
ssize_t error;
struct aa_loaddata *data;
struct aa_profile *profile = aa_current_profile();
- const char *op = binop == PROF_ADD ? OP_PROF_LOAD : OP_PROF_REPL;
/* high level check about policy management - fine grained in
* below after unpack
*/
- error = aa_may_manage_policy(profile, ns, op);
+ error = aa_may_manage_policy(profile, ns, mask);
if (error)
return error;
error = PTR_ERR(data);
if (!IS_ERR(data)) {
error = aa_replace_profiles(ns ? ns : profile->ns, profile,
- binop, data);
+ mask, data);
aa_put_loaddata(data);
}
loff_t *pos)
{
struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
- int error = policy_update(PROF_ADD, buf, size, pos, ns);
+ int error = policy_update(AA_MAY_LOAD_POLICY, buf, size, pos, ns);
aa_put_ns(ns);
size_t size, loff_t *pos)
{
struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
- int error = policy_update(PROF_REPLACE, buf, size, pos, ns);
-
+ int error = policy_update(AA_MAY_LOAD_POLICY | AA_MAY_REPLACE_POLICY,
+ buf, size, pos, ns);
aa_put_ns(ns);
return error;
/* high level check about policy management - fine grained in
* below after unpack
*/
- error = aa_may_manage_policy(profile, ns, OP_PROF_RM);
+ error = aa_may_manage_policy(profile, ns, AA_MAY_REMOVE_POLICY);
if (error)
goto out;
extern enum profile_mode aa_g_profile_mode;
+#define AA_MAY_LOAD_POLICY AA_MAY_APPEND
+#define AA_MAY_REPLACE_POLICY AA_MAY_WRITE
+#define AA_MAY_REMOVE_POLICY AA_MAY_DELETE
+
void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new);
void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);
struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name);
ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- bool noreplace, struct aa_loaddata *udata);
+ u32 mask, struct aa_loaddata *udata);
ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *profile,
char *name, size_t size);
void __aa_profile_list_release(struct list_head *head);
bool policy_view_capable(struct aa_ns *ns);
bool policy_admin_capable(struct aa_ns *ns);
int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns,
- const char *op);
+ u32 mask);
#endif /* __AA_POLICY_H */
*
* Returns: 0 if the task is allowed to manipulate policy else error
*/
-int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns,
- const char *op)
+int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns, u32 mask)
{
+ const char *op;
+
+ if (mask & AA_MAY_REMOVE_POLICY)
+ op = OP_PROF_RM;
+ else if (mask & AA_MAY_REPLACE_POLICY)
+ op = OP_PROF_REPL;
+ else
+ op = OP_PROF_LOAD;
+
/* check if loading policy is locked out */
if (aa_g_lock_policy)
- return audit_policy(profile, op, NULL, NULL,
- "policy_locked", -EACCES);
+ return audit_policy(profile, op, NULL, NULL, "policy_locked",
+ -EACCES);
if (!policy_admin_capable(ns))
- return audit_policy(profile, op, NULL, NULL,
- "not policy admin", -EACCES);
+ return audit_policy(profile, op, NULL, NULL, "not policy admin",
+ -EACCES);
/* TODO: add fine grained mediation of policy loads */
return 0;
* aa_replace_profiles - replace profile(s) on the profile list
* @view: namespace load is viewed from
* @label: label that is attempting to load/replace policy
- * @noreplace: true if only doing addition, no replacement allowed
+ * @mask: permission mask
* @udata: serialized data stream (NOT NULL)
*
* unpack and replace a profile on the profile list and uses of that profile
* Returns: size of data consumed else error code on failure.
*/
ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- bool noreplace, struct aa_loaddata *udata)
+ u32 mask, struct aa_loaddata *udata)
{
const char *ns_name, *info = NULL;
struct aa_ns *ns = NULL;
struct aa_load_ent *ent, *tmp;
struct aa_loaddata *rawdata_ent;
- const char *op = OP_PROF_REPL;
+ const char *op;
ssize_t count, error;
-
LIST_HEAD(lh);
+ op = mask & AA_MAY_REPLACE_POLICY ? OP_PROF_REPL : OP_PROF_LOAD;
aa_get_loaddata(udata);
/* released below */
error = aa_unpack(udata, &lh, &ns_name);
struct aa_policy *policy;
ent->new->rawdata = aa_get_loaddata(udata);
- error = __lookup_replace(ns, ent->new->base.hname, noreplace,
+ error = __lookup_replace(ns, ent->new->base.hname,
+ !(mask & AA_MAY_REPLACE_POLICY),
&ent->old, &info);
if (error)
goto fail_lock;
if (ent->new->rename) {
error = __lookup_replace(ns, ent->new->rename,
- noreplace, &ent->rename,
- &info);
+ !(mask & AA_MAY_REPLACE_POLICY),
+ &ent->rename, &info);
if (error)
goto fail_lock;
}