/* * Setup a watch permissions. * Returns a 1 on success & -1 on failure. */ static int audit_setup_perms(struct audit_rule_data *rule, const char *opt) { unsigned int i, len, val = 0; len = strlen(opt); if (len > 4) return -1; for (i = 0; i < len; i++) { switch (tolower(opt[i])) { case 'r': val |= AUDIT_PERM_READ; break; case 'w': val |= AUDIT_PERM_WRITE; break; case 'x': val |= AUDIT_PERM_EXEC; break; case 'a': val |= AUDIT_PERM_ATTR; break; default: fprintf(stderr, "Permission %c isn't supported\n", opt[i]); return -1; } } if (audit_update_watch_perms(rule_new, val) == 0) { _audit_permadded = 1; return 1; } return -1; }
static int audit_rules_parse_and_add(int audit_fd, char *line) { char *argv[AUDIT_MAX_FIELDS]; int argc; int rc = 0; int added_rule = 0; char p; int opt; size_t len; struct audit_rule_data *rule; /* Strip crlf */ line[strlen(line) -1] = '\0'; argv[0] = "auditd"; for (argc=1; argc < AUDIT_MAX_FIELDS - 1; argc++) { argv[argc] = strsep(&line, " \n\r"); if (argv[argc] == NULL) { break; } } optind = 0; char *field; char *oper; size_t length; int audit_field; int oper_field; int i; while ((opt = getopt(argc, argv, "w:e:p:F:")) != -1) { switch(opt) { case 'w': if (audit_add_dir(&rule, optarg)) { SLOGE("Error adding rule"); return -1; } added_rule = 1; break; case 'e': if (audit_set_enabled(audit_fd, strtoul(optarg, NULL, 10))) { return -1; } break; case 'F': if (added_rule == 0) { SLOGE("Specify rule type before permissions"); return -1; } length = strcspn(optarg, OPERS); field = strndup(optarg, length); if (field == NULL) { SLOGE("Out of memory!"); return -1; } audit_field = string_to_audit_field(field); if (audit_field == 0) { SLOGE("Invalid field: %s", field); free(field); return -1; } free(field); optarg = &optarg[length]; length = strspn(optarg, OPERS); oper = strndup(optarg, length); oper_field = string_to_oper(oper); if (oper_field == -1) { SLOGE("Invalid operator: %s", oper); free(oper); return -1; } free(oper); optarg = &optarg[length]; if (audit_add_field(rule, audit_field, oper_field, optarg) < 0) { SLOGE("Adding field failed"); return -1; } break; case 'p': if (added_rule == 0) { SLOGE("Specify rule type before permissions"); return -1; } uint32_t perms = 0; for (len=0; len < strlen(optarg); len++) { switch(optarg[len]) { case 'w': perms |= AUDIT_PERM_WRITE; break; case 'e': perms |= AUDIT_PERM_EXEC; break; case 'r': perms |= AUDIT_PERM_READ; break; case 'a': perms |= AUDIT_PERM_ATTR; break; default: SLOGE("Unknown permission %c", optarg[len]); break; } } if (audit_update_watch_perms(rule, perms)) { SLOGE("Could not set perms on rule"); return -1; } break; case '?': SLOGE("Unsupported option: %c", optopt); break; } } if (added_rule) { rc = audit_send(audit_fd, AUDIT_ADD_RULE, rule, sizeof(*rule) + rule->buflen); free(rule); } return rc; }