}
/**
- * smk_parse_rule - parse subject, object and access type
+ * smk_parse_rule - parse Smack rule from load string
* @data: string to be parsed whose size is SMK_LOADLEN
- * @rule: parsed entities are stored in here
+ * @rule: Smack rule
+ * @import: if non-zero, import labels
*/
-static int smk_parse_rule(const char *data, struct smack_rule *rule)
+static int smk_parse_rule(const char *data, struct smack_rule *rule, int import)
{
- rule->smk_subject = smk_import(data, 0);
- if (rule->smk_subject == NULL)
- return -1;
+ char smack[SMK_LABELLEN];
+ struct smack_known *skp;
- rule->smk_object = smk_import(data + SMK_LABELLEN, 0);
- if (rule->smk_object == NULL)
- return -1;
+ if (import) {
+ rule->smk_subject = smk_import(data, 0);
+ if (rule->smk_subject == NULL)
+ return -1;
+
+ rule->smk_object = smk_import(data + SMK_LABELLEN, 0);
+ if (rule->smk_object == NULL)
+ return -1;
+ } else {
+ smk_parse_smack(data, 0, smack);
+ skp = smk_find_entry(smack);
+ if (skp == NULL)
+ return -1;
+ rule->smk_subject = skp->smk_known;
+
+ smk_parse_smack(data + SMK_LABELLEN, 0, smack);
+ skp = smk_find_entry(smack);
+ if (skp == NULL)
+ return -1;
+ rule->smk_object = skp->smk_known;
+ }
rule->smk_access = 0;
goto out;
}
- if (smk_parse_rule(data, rule))
+ if (smk_parse_rule(data, rule, 1))
goto out_free_rule;
if (rule_list == NULL) {
{
struct smack_rule rule;
char *data;
-
- if (!capable(CAP_MAC_ADMIN))
- return -EPERM;
+ int res;
data = simple_transaction_get(file, buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
- if (count < SMK_LOADLEN || smk_parse_rule(data, &rule))
+ if (count < SMK_LOADLEN || smk_parse_rule(data, &rule, 0))
return -EINVAL;
- data[0] = smk_access(rule.smk_subject, rule.smk_object,
- rule.smk_access, NULL) == 0;
+ res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access,
+ NULL);
+ data[0] = res == 0 ? '1' : '0';
+ data[1] = '\0';
- simple_transaction_set(file, 1);
+ simple_transaction_set(file, 2);
return SMK_LOADLEN;
}
[SMK_LOAD_SELF] = {
"load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO},
[SMK_ACCESSES] = {
- "access", &smk_access_ops, S_IRUGO|S_IWUSR},
+ "access", &smk_access_ops, S_IRUGO|S_IWUGO},
/* last one */
{""}
};