This is the user space component of this patch.
This patch basically modifies the manner in which the field/value pairs
are split. Previously, the code simply split on "=" and flipped a bit
if there was a "!" just before the "=".
I had to make this a bit smarter, and I think I did it cleanly using
strstr(). Each of the six operators (!=, >=, <=, =, >, <) are searched
for in the string until one "hits". Note that the 2-character
comparators are searched for first (for obvious reasons).
When there's a hit, the comparator bytes are overwritten with the null
byte to split the string, and the "f" and "v" (field and value,
respectively) pointers are set appropriately, as well as the "op"
variable, which is the bitmask of the corresponding comparator.
This op bitmask is OR'd with the field and netlink goes about passing
this information just as it previously did.
Note that I also constructed the symbol translation table, which is
useful to convert the operator bitmask constants back to their prettier
symbols (for error reporting as below).
My only concern is that *f and *v were const before, but now I'm
modifying them, overwriting the operator bytes. I suppose I could
strdup() this and work on that. Let me know if that's preferred.
Comments welcome.
:-Dustin
diff -urpN audit-1.0.7/lib/libaudit.c
audit-1.0.7-operators/lib/libaudit.c
--- audit-1.0.7/lib/libaudit.c 2005-10-17 12:40:22.000000000 -0500
+++ audit-1.0.7-operators/lib/libaudit.c 2005-10-21 11:37:31.000000000 -0500
@@ -615,26 +615,50 @@ int audit_rule_field(struct audit_rule *
int audit_rule_fieldpair(struct audit_rule *rule, const char *pair, int flags)
{
char buf[128];
- const char *f = pair;
- const char *v = strchr(pair, '=');
+ char *f = pair;
+ char *v;
+ int op;
int field;
int negated = 0;
int vlen;
-
+
+ /* look for 2-char operators first
+ then look for 1-char operators afterwards
+ when found, null out the bytes under the operators to split
+ and set value pointer just past operator bytes
+ */
+ if ( v = strstr(pair, "!=") ) {
+ *v++ = '\0';
+ *v++ = '\0';
+ op = AUDIT_NOT_EQUAL;
+ } else if ( v = strstr(pair, ">=") ) {
+ *v++ = '\0';
+ *v++ = '\0';
+ op = AUDIT_GREATER_THAN_OR_EQUAL;
+ } else if ( v = strstr(pair, "<=") ) {
+ *v++ = '\0';
+ *v++ = '\0';
+ op = AUDIT_LESS_THAN_OR_EQUAL;
+ } else if ( v = strstr(pair, "=") ) {
+ *v++ = '\0';
+ op = AUDIT_EQUAL;
+ } else if ( v = strstr(pair, ">") ) {
+ *v++ = '\0';
+ op = AUDIT_GREATER_THAN;
+ } else if ( v = strstr(pair, "<") ) {
+ *v++ = '\0';
+ op = AUDIT_LESS_THAN;
+ }
+
if (!f || !v || f == v)
return -1;
- if (v > pair && v[-1] == '!')
- negated = 1;
-
- snprintf(buf, sizeof(buf), "%*.*s", (int)(v-f-negated),
- (int)(v-f-negated), f);
- audit_msg(LOG_DEBUG,"buf=%s\n", buf);
- if ((field = audit_name_to_field(buf)) < 0)
+ audit_msg(LOG_DEBUG,"buf=%s\n", f);
+ if ((field = audit_name_to_field(f)) < 0)
return -2;
- v++;
- audit_msg(LOG_DEBUG,"f%d%s%s\n", field, negated ? "!=" :
"=", v);
- rule->fields[rule->field_count] = field | (negated ? AUDIT_NEGATE : 0);
+
+ audit_msg(LOG_DEBUG,"f%d%s%s\n", field, audit_operator_to_symbol(op), v);
+ rule->fields[rule->field_count] = field | op;
switch (field)
{
case AUDIT_UID:
diff -urpN audit-1.0.7/lib/lookup_table.c audit-1.0.7-operators/lib/lookup_table.c
--- audit-1.0.7/lib/lookup_table.c 2005-10-19 13:26:04.000000000 -0500
+++ audit-1.0.7-operators/lib/lookup_table.c 2005-10-20 17:28:40.000000000 -0500
@@ -220,6 +220,16 @@ static struct int_transtab elftab[] = {
};
#define AUDIT_ELF_NAMES (sizeof(elftab)/sizeof(elftab[0]))
+static struct transtab optab[] = {
+ { AUDIT_EQUAL, "=" },
+ { AUDIT_NOT_EQUAL, "!=" },
+ { AUDIT_GREATER_THAN, ">" },
+ { AUDIT_GREATER_THAN_OR_EQUAL, ">=" },
+ { AUDIT_LESS_THAN, "<" },
+ { AUDIT_LESS_THAN_OR_EQUAL, "<=" }
+};
+#define AUDIT_NUM_OPERATORS (sizeof(optab)/sizeof(optab[0]))
+
static int audit_lookup_name(struct transtab *table, int length,
const char *name)
{
@@ -367,3 +377,7 @@ int audit_elf_to_machine(unsigned int el
return -1;
}
+const char *audit_operator_to_symbol(int op)
+{
+ return audit_lookup_number(optab, AUDIT_NUM_OPERATORS, op);
+}