@@ -1326,6 +1326,15 @@ void sec_audit_logger_json(modsec_rec *msr) {
13261326for (i = 0 ;i < msr -> matched_rules -> nelts ;i ++ ) {
13271327rule = ((msre_rule * * )msr -> matched_rules -> elts )[i ];
13281328if ((rule != NULL )&& (rule -> actionset != NULL )&& rule -> actionset -> is_chained && (rule -> chain_starter == NULL )) {
1329+ /*
1330+ * create a separate map for each rule chain
1331+ * this makes it a lot easier to search for partial chains
1332+ */
1333+ yajl_gen_map_open (g );// map for this chain
1334+ yajl_kv_bool (g ,"chain" ,1 );
1335+ yajl_string (g ,"rules" );
1336+ yajl_gen_array_open (g );// array for the rules
1337+
13291338write_rule_json (msr ,rule ,g );
13301339do {
13311340if (rule -> ruleset != NULL ) {
@@ -1344,10 +1353,23 @@ void sec_audit_logger_json(modsec_rec *msr) {
13441353 }
13451354rule = next_rule ;
13461355 }while (rule != NULL && rule -> actionset != NULL && rule -> actionset -> is_chained );
1356+ yajl_gen_array_close (g );
1357+
1358+ yajl_kv_bool (g ,"full_chain_match" ,present );// if one of the rules didnt match, present is set to 0
1359+ yajl_gen_map_close (g );// close the map for this chain
13471360 }else {
1361+ yajl_gen_map_open (g );
1362+
1363+ yajl_kv_bool (g ,"chain" ,0 );
1364+ yajl_string (g ,"rules" );// this really should be 'rule', but we're keeping in line with other chain maps
1365+
1366+ yajl_gen_array_open (g );
13481367if ((rule != NULL )&& (rule -> actionset != NULL )&& !rule -> actionset -> is_chained && (rule -> chain_starter == NULL )) {
13491368write_rule_json (msr ,rule ,g );
13501369 }
1370+ yajl_gen_array_close (g );
1371+
1372+ yajl_gen_map_close (g );
13511373 }
13521374 }
13531375yajl_gen_array_close (g );// matched_rules top-level key is finished