PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/code_to_review/audit-1.7.10/auparse/auparse.c

http://chirico.googlecode.com/
C | 1363 lines | 1033 code | 155 blank | 175 comment | 287 complexity | ff2f831efaa27b60f2198b30d86d5a26 MD5 | raw file
Possible License(s): GPL-2.0, Apache-2.0, GPL-3.0, AGPL-1.0
  1. /* auparse.c --
  2. * Copyright 2006-08 Red Hat Inc., Durham, North Carolina.
  3. * All Rights Reserved.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. * Authors:
  20. * Steve Grubb <sgrubb@redhat.com>
  21. */
  22. #include "config.h"
  23. #include "expression.h"
  24. #include "internal.h"
  25. #include "auparse.h"
  26. #include "interpret.h"
  27. #include <errno.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <unistd.h>
  31. #include <regex.h>
  32. #include <stdio_ext.h>
  33. static int debug = 0;
  34. /* like strchr except string is delimited by length, not null byte */
  35. static char *strnchr(const char *s, int c, size_t n)
  36. {
  37. char *p_char;
  38. const char *p_end = s + n;
  39. for (p_char = (char *)s; p_char < p_end && *p_char != c; p_char++);
  40. if (p_char == p_end) return NULL;
  41. return p_char;
  42. }
  43. static int setup_log_file_array(auparse_state_t *au)
  44. {
  45. struct daemon_conf config;
  46. char *filename, **tmp;
  47. int len, num = 0, i = 0;
  48. /* Load config so we know where logs are */
  49. set_aumessage_mode(MSG_STDERR, DBG_NO);
  50. load_config(&config, TEST_SEARCH);
  51. /* for each file */
  52. len = strlen(config.log_file) + 16;
  53. filename = malloc(len);
  54. if (!filename) {
  55. fprintf(stderr, "No memory\n");
  56. free_config(&config);
  57. return 1;
  58. }
  59. /* Find oldest log file */
  60. snprintf(filename, len, "%s", config.log_file);
  61. do {
  62. if (access(filename, R_OK) != 0)
  63. break;
  64. num++;
  65. snprintf(filename, len, "%s.%d", config.log_file, num);
  66. } while (1);
  67. num--;
  68. tmp = malloc((num+2)*sizeof(char *));
  69. /* Got it, now process logs from last to first */
  70. if (num > 0)
  71. snprintf(filename, len, "%s.%d", config.log_file, num);
  72. else
  73. snprintf(filename, len, "%s", config.log_file);
  74. do {
  75. tmp[i++] = strdup(filename);
  76. /* Get next log file */
  77. num--;
  78. if (num > 0)
  79. snprintf(filename, len, "%s.%d", config.log_file, num);
  80. else if (num == 0)
  81. snprintf(filename, len, "%s", config.log_file);
  82. else
  83. break;
  84. } while (1);
  85. free_config(&config);
  86. free(filename);
  87. // Terminate the list
  88. tmp[i] = NULL;
  89. au->source_list = tmp;
  90. return 0;
  91. }
  92. /* General functions that affect operation of the library */
  93. auparse_state_t *auparse_init(ausource_t source, const void *b)
  94. {
  95. char **tmp, **bb = (char **)b, *buf = (char *)b;
  96. int n, i;
  97. size_t size, len;
  98. auparse_state_t *au = malloc(sizeof(auparse_state_t));
  99. if (au == NULL) {
  100. errno = ENOMEM;
  101. return NULL;
  102. }
  103. au->in = NULL;
  104. au->source_list = NULL;
  105. databuf_init(&au->databuf, 0, 0);
  106. au->callback = NULL;
  107. au->callback_user_data = NULL;
  108. au->callback_user_data_destroy = NULL;
  109. switch (source)
  110. {
  111. case AUSOURCE_LOGS:
  112. if (geteuid()) {
  113. errno = EPERM;
  114. goto bad_exit;
  115. }
  116. setup_log_file_array(au);
  117. break;
  118. case AUSOURCE_FILE:
  119. if (access(b, R_OK))
  120. goto bad_exit;
  121. tmp = malloc(2*sizeof(char *));
  122. tmp[0] = strdup(b);
  123. tmp[1] = NULL;
  124. au->source_list = tmp;
  125. break;
  126. case AUSOURCE_FILE_ARRAY:
  127. n = 0;
  128. while (bb[n]) {
  129. if (access(bb[n], R_OK))
  130. goto bad_exit;
  131. n++;
  132. }
  133. tmp = malloc((n+1)*sizeof(char *));
  134. for (i=0; i<n; i++)
  135. tmp[i] = strdup(bb[i]);
  136. tmp[n] = NULL;
  137. au->source_list = tmp;
  138. break;
  139. case AUSOURCE_BUFFER:
  140. buf = buf;
  141. len = strlen(buf);
  142. if (databuf_init(&au->databuf, len,
  143. DATABUF_FLAG_PRESERVE_HEAD) < 0)
  144. goto bad_exit;
  145. if (databuf_append(&au->databuf, buf, len) < 0)
  146. goto bad_exit;
  147. break;
  148. case AUSOURCE_BUFFER_ARRAY:
  149. size = 0;
  150. for (n = 0; (buf = bb[n]); n++) {
  151. len = strlen(bb[n]);
  152. if (bb[n][len-1] != '\n') {
  153. size += len + 1;
  154. } else {
  155. size += len;
  156. }
  157. }
  158. if (databuf_init(&au->databuf, size,
  159. DATABUF_FLAG_PRESERVE_HEAD) < 0)
  160. goto bad_exit;
  161. for (n = 0; (buf = bb[n]); n++) {
  162. len = strlen(buf);
  163. if (databuf_append(&au->databuf, buf, len) < 0)
  164. goto bad_exit;
  165. }
  166. break;
  167. case AUSOURCE_DESCRIPTOR:
  168. n = (long)b;
  169. au->in = fdopen(n, "r");
  170. break;
  171. case AUSOURCE_FILE_POINTER:
  172. au->in = (FILE *)b;
  173. break;
  174. case AUSOURCE_FEED:
  175. if (databuf_init(&au->databuf, 0, 0) < 0) goto bad_exit;
  176. break;
  177. default:
  178. errno = EINVAL;
  179. return NULL;
  180. break;
  181. }
  182. au->source = source;
  183. au->list_idx = 0;
  184. au->line_number = 0;
  185. au->next_buf = NULL;
  186. au->off = 0;
  187. au->cur_buf = NULL;
  188. au->line_pushed = 0;
  189. aup_list_create(&au->le);
  190. au->parse_state = EVENT_EMPTY;
  191. au->expr = NULL;
  192. au->find_field = NULL;
  193. au->search_where = AUSEARCH_STOP_EVENT;
  194. au->regex_valid = 0;
  195. return au;
  196. bad_exit:
  197. databuf_free(&au->databuf);
  198. free(au);
  199. return NULL;
  200. }
  201. void auparse_add_callback(auparse_state_t *au, auparse_callback_ptr callback,
  202. void *user_data, user_destroy user_destroy_func)
  203. {
  204. if (au->callback_user_data_destroy) {
  205. (*au->callback_user_data_destroy)(au->callback_user_data);
  206. au->callback_user_data = NULL;
  207. }
  208. au->callback = callback;
  209. au->callback_user_data = user_data;
  210. au->callback_user_data_destroy = user_destroy_func;
  211. }
  212. static void consume_feed(auparse_state_t *au, int flush)
  213. {
  214. while (auparse_next_event(au) > 0) {
  215. if (au->callback) {
  216. (*au->callback)(au, AUPARSE_CB_EVENT_READY,
  217. au->callback_user_data);
  218. }
  219. }
  220. if (flush) {
  221. // FIXME: might need a call here to force auparse_next_event()
  222. // to consume any partial data not fully consumed.
  223. if (au->parse_state == EVENT_ACCUMULATING) {
  224. // Emit the event, set event cursors to initial position
  225. aup_list_first(&au->le);
  226. aup_list_first_field(&au->le);
  227. au->parse_state = EVENT_EMITTED;
  228. if (au->callback) {
  229. (*au->callback)(au, AUPARSE_CB_EVENT_READY,
  230. au->callback_user_data);
  231. }
  232. }
  233. }
  234. }
  235. int auparse_feed(auparse_state_t *au, const char *data, size_t data_len)
  236. {
  237. if (databuf_append(&au->databuf, data, data_len) < 0)
  238. return -1;
  239. consume_feed(au, 0);
  240. return 0;
  241. }
  242. int auparse_flush_feed(auparse_state_t *au)
  243. {
  244. consume_feed(au, 1);
  245. return 0;
  246. }
  247. int auparse_reset(auparse_state_t *au)
  248. {
  249. if (au == NULL) {
  250. errno = EINVAL;
  251. return -1;
  252. }
  253. aup_list_clear(&au->le);
  254. au->parse_state = EVENT_EMPTY;
  255. switch (au->source)
  256. {
  257. case AUSOURCE_LOGS:
  258. case AUSOURCE_FILE:
  259. case AUSOURCE_FILE_ARRAY:
  260. if (au->in) {
  261. fclose(au->in);
  262. au->in = NULL;
  263. }
  264. /* Fall through */
  265. case AUSOURCE_DESCRIPTOR:
  266. case AUSOURCE_FILE_POINTER:
  267. if (au->in)
  268. rewind(au->in);
  269. /* Fall through */
  270. case AUSOURCE_BUFFER:
  271. case AUSOURCE_BUFFER_ARRAY:
  272. au->list_idx = 0;
  273. au->line_number = 0;
  274. au->off = 0;
  275. databuf_reset(&au->databuf);
  276. break;
  277. default:
  278. return -1;
  279. }
  280. return 0;
  281. }
  282. /* Add EXPR to AU, using HOW to select the combining operator.
  283. On success, return 0.
  284. On error, free EXPR set errno and return -1.
  285. NOTE: EXPR is freed on error! */
  286. static int add_expr(auparse_state_t *au, struct expr *expr, ausearch_rule_t how)
  287. {
  288. if (au->expr == NULL)
  289. au->expr = expr;
  290. else if (how == AUSEARCH_RULE_CLEAR) {
  291. expr_free(au->expr);
  292. au->expr = expr;
  293. } else {
  294. struct expr *e;
  295. e = expr_create_binary(how == AUSEARCH_RULE_OR ? EO_OR : EO_AND,
  296. au->expr, expr);
  297. if (e == NULL) {
  298. int err;
  299. err = errno;
  300. expr_free(expr);
  301. errno = err;
  302. return -1;
  303. }
  304. au->expr = e;
  305. }
  306. return 0;
  307. }
  308. static int ausearch_add_item_internal(auparse_state_t *au, const char *field,
  309. const char *op, const char *value, ausearch_rule_t how, unsigned op_eq,
  310. unsigned op_ne)
  311. {
  312. struct expr *expr;
  313. // Make sure there's a field
  314. if (field == NULL)
  315. goto err_out;
  316. // Do not allow regex to get replaced this way
  317. if (au->regex_valid != 0)
  318. goto err_out;
  319. // Make sure how is within range
  320. if (how < AUSEARCH_RULE_CLEAR || how > AUSEARCH_RULE_AND)
  321. goto err_out;
  322. // All pre-checks are done, build a rule
  323. if (strcmp(op, "exists") == 0)
  324. expr = expr_create_field_exists(field);
  325. else {
  326. unsigned t_op;
  327. if (strcmp(op, "=") == 0)
  328. t_op = op_eq;
  329. else if (strcmp(op, "!=") == 0)
  330. t_op = op_ne;
  331. else
  332. goto err_out;
  333. if (value == NULL)
  334. goto err_out;
  335. expr = expr_create_comparison(field, t_op, value);
  336. }
  337. if (expr == NULL)
  338. return -1;
  339. if (add_expr(au, expr, how) != 0)
  340. return -1; /* expr is freed by add_expr() */
  341. return 0;
  342. err_out:
  343. errno = EINVAL;
  344. return -1;
  345. }
  346. int ausearch_add_item(auparse_state_t *au, const char *field, const char *op,
  347. const char *value, ausearch_rule_t how)
  348. {
  349. return ausearch_add_item_internal(au, field, op, value, how, EO_RAW_EQ,
  350. EO_RAW_NE);
  351. }
  352. int ausearch_add_interpreted_item(auparse_state_t *au, const char *field,
  353. const char *op, const char *value, ausearch_rule_t how)
  354. {
  355. return ausearch_add_item_internal(au, field, op, value, how,
  356. EO_INTERPRETED_EQ, EO_INTERPRETED_NE);
  357. }
  358. int ausearch_add_timestamp_item(auparse_state_t *au, const char *op, time_t sec,
  359. unsigned milli, ausearch_rule_t how)
  360. {
  361. static const struct {
  362. unsigned value;
  363. const char name[3];
  364. } ts_tab[] = {
  365. {EO_VALUE_LT, "<"},
  366. {EO_VALUE_LE, "<="},
  367. {EO_VALUE_GE, ">="},
  368. {EO_VALUE_GT, ">"},
  369. {EO_VALUE_EQ, "="},
  370. };
  371. struct expr *expr;
  372. size_t i;
  373. unsigned t_op;
  374. for (i = 0; i < sizeof(ts_tab) / sizeof(*ts_tab); i++) {
  375. if (strcmp(ts_tab[i].name, op) == 0)
  376. goto found_op;
  377. }
  378. goto err_out;
  379. found_op:
  380. t_op = ts_tab[i].value;
  381. if (milli >= 1000)
  382. goto err_out;
  383. // Do not allow regex to get replaced this way
  384. if (au->regex_valid != 0)
  385. goto err_out;
  386. // Make sure how is within range
  387. if (how < AUSEARCH_RULE_CLEAR || how > AUSEARCH_RULE_AND)
  388. goto err_out;
  389. // All pre-checks are done, build a rule
  390. expr = expr_create_timestamp_comparison(t_op, sec, milli);
  391. if (expr == NULL)
  392. return -1;
  393. if (add_expr(au, expr, how) != 0)
  394. return -1; /* expr is freed by add_expr() */
  395. return 0;
  396. err_out:
  397. errno = EINVAL;
  398. return -1;
  399. }
  400. int ausearch_add_expression(auparse_state_t *au, const char *expression,
  401. char **error, ausearch_rule_t how)
  402. {
  403. struct expr *expr;
  404. // Do not allow regex to get replaced this way
  405. if (au->regex_valid != 0)
  406. goto err_einval;
  407. if (how < AUSEARCH_RULE_CLEAR || how > AUSEARCH_RULE_AND)
  408. goto err_einval;
  409. expr = expr_parse(expression, error);
  410. if (expr == NULL) {
  411. errno = EINVAL;
  412. return -1;
  413. }
  414. if (add_expr(au, expr, how) != 0)
  415. goto err; /* expr is freed by add_expr() */
  416. return 0;
  417. err_einval:
  418. errno = EINVAL;
  419. err:
  420. *error = NULL;
  421. return -1;
  422. }
  423. int ausearch_add_regex(auparse_state_t *au, const char *expr)
  424. {
  425. int rc;
  426. // Make sure there's an expression
  427. if (expr == NULL)
  428. goto err_out;
  429. if (au->regex_valid != 0 || au->expr != NULL)
  430. goto err_out;
  431. // Compile expression now to make sure the expression is correct
  432. rc = regcomp(&au->regex, expr, REG_EXTENDED|REG_NOSUB);
  433. if (rc) {
  434. goto err_out;
  435. }
  436. au->regex_valid = 1;
  437. return 0;
  438. err_out:
  439. errno = EINVAL;
  440. return -1;
  441. }
  442. int ausearch_set_stop(auparse_state_t *au, austop_t where)
  443. {
  444. if (where < AUSEARCH_STOP_EVENT || where > AUSEARCH_STOP_FIELD) {
  445. errno = EINVAL;
  446. return -1;
  447. }
  448. au->search_where = where;
  449. return 0;
  450. }
  451. void ausearch_clear(auparse_state_t *au)
  452. {
  453. if (au->regex_valid != 0) {
  454. regfree(&au->regex);
  455. au->regex_valid = 0;
  456. }
  457. if (au->expr != NULL) {
  458. expr_free(au->expr);
  459. au->expr = NULL;
  460. }
  461. au->search_where = AUSEARCH_STOP_EVENT;
  462. }
  463. hidden_def(ausearch_clear)
  464. void auparse_destroy(auparse_state_t *au)
  465. {
  466. if (au->source_list) {
  467. int n = 0;
  468. while (au->source_list[n])
  469. free(au->source_list[n++]);
  470. free(au->source_list);
  471. au->source_list = NULL;
  472. }
  473. au->next_buf = NULL;
  474. free(au->cur_buf);
  475. au->cur_buf = NULL;
  476. aup_list_clear(&au->le);
  477. au->parse_state = EVENT_EMPTY;
  478. free(au->find_field);
  479. au->find_field = NULL;
  480. ausearch_clear(au);
  481. databuf_free(&au->databuf);
  482. if (au->callback_user_data_destroy) {
  483. (*au->callback_user_data_destroy)(au->callback_user_data);
  484. au->callback_user_data = NULL;
  485. }
  486. aulookup_destroy_uid_list();
  487. aulookup_destroy_gid_list();
  488. if (au->in) {
  489. fclose(au->in);
  490. au->in = NULL;
  491. }
  492. free(au);
  493. }
  494. /* alloc a new buffer, cur_buf which contains a null terminated line
  495. * without a newline (note, this implies the line may be empty (strlen == 0)) if
  496. * successfully read a blank line (e.g. containing only a single newline).
  497. * cur_buf will have been newly allocated with malloc.
  498. *
  499. * Note: cur_buf will be freed the next time this routine is called if
  500. * cur_buf is not NULL, callers who retain a reference to the cur_buf
  501. * pointer will need to set cur_buf to NULL to cause the previous cur_buf
  502. * allocation to persist.
  503. *
  504. * Returns:
  505. * 1 if successful (errno == 0)
  506. * 0 if non-blocking input unavailable (errno == 0)
  507. * -1 if error (errno contains non-zero error code)
  508. * -2 if EOF (errno == 0)
  509. */
  510. static int readline_file(auparse_state_t *au)
  511. {
  512. ssize_t rc;
  513. char *p_last_char;
  514. size_t n = 0;
  515. if (au->cur_buf != NULL) {
  516. free(au->cur_buf);
  517. au->cur_buf = NULL;
  518. }
  519. if (au->in == NULL) {
  520. errno = EBADF;
  521. return -1;
  522. }
  523. if ((rc = getline(&au->cur_buf, &n, au->in)) <= 0) {
  524. // Note: getline always malloc's if lineptr==NULL or n==0,
  525. // on failure malloc'ed memory is left uninitialized,
  526. // caller must free it.
  527. free(au->cur_buf);
  528. au->cur_buf = NULL;
  529. // Note: feof() does not set errno
  530. if (feof(au->in)) {
  531. // return EOF condition
  532. errno = 0;
  533. return -2;
  534. }
  535. // return error condition, error code in errno
  536. return -1;
  537. }
  538. p_last_char = au->cur_buf + (rc-1);
  539. if (*p_last_char == '\n') { /* nuke newline */
  540. *p_last_char = 0;
  541. }
  542. // return success
  543. errno = 0;
  544. return 1;
  545. }
  546. /* malloc & copy a line into cur_buf from the internal buffer,
  547. * next_buf. cur_buf will contain a null terminated line without a
  548. * newline (note, this implies the line may be empty (strlen == 0)) if
  549. * successfully read a blank line (e.g. containing only a single
  550. * newline).
  551. *
  552. * Note: cur_buf will be freed the next time this routine is called if
  553. * cur_buf is not NULL, callers who retain a reference to the cur_buf
  554. * pointer will need to set cur_buf to NULL to cause the previous cur_buf
  555. * allocation to persist.
  556. *
  557. * Returns:
  558. * 1 if successful (errno == 0)
  559. * 0 if non-blocking input unavailable (errno == 0)
  560. * -1 if error (errno contains non-zero error code)
  561. * -2 if EOF (errno == 0)
  562. */
  563. static int readline_buf(auparse_state_t *au)
  564. {
  565. char *p_newline=NULL;
  566. size_t line_len;
  567. if (au->cur_buf != NULL) {
  568. free(au->cur_buf);
  569. au->cur_buf = NULL;
  570. }
  571. //if (debug) databuf_print(&au->databuf, 1, "readline_buf");
  572. if (au->databuf.len == 0) {
  573. // return EOF condition
  574. errno = 0;
  575. return -2;
  576. }
  577. if ((p_newline = strnchr(databuf_beg(&au->databuf), '\n',
  578. au->databuf.len)) != NULL) {
  579. line_len = p_newline - databuf_beg(&au->databuf);
  580. /* dup the line */
  581. au->cur_buf = malloc(line_len+1); // +1 for null terminator
  582. if (au->cur_buf == NULL)
  583. return -1; // return error condition, errno set
  584. strncpy(au->cur_buf, databuf_beg(&au->databuf), line_len);
  585. au->cur_buf[line_len] = 0;
  586. if (databuf_advance(&au->databuf, line_len+1) < 0)
  587. return -1;
  588. // return success
  589. errno = 0;
  590. return 1;
  591. } else {
  592. // return no data available
  593. errno = 0;
  594. return 0;
  595. }
  596. }
  597. static int str2event(char *s, au_event_t *e)
  598. {
  599. char *ptr;
  600. errno = 0;
  601. ptr = strchr(s+10, ':');
  602. if (ptr) {
  603. e->serial = strtoul(ptr+1, NULL, 10);
  604. *ptr = 0;
  605. if (errno)
  606. return -1;
  607. } else
  608. e->serial = 0;
  609. ptr = strchr(s, '.');
  610. if (ptr) {
  611. e->milli = strtoul(ptr+1, NULL, 10);
  612. *ptr = 0;
  613. if (errno)
  614. return -1;
  615. } else
  616. e->milli = 0;
  617. e->sec = strtoul(s, NULL, 10);
  618. if (errno)
  619. return -1;
  620. return 0;
  621. }
  622. /* Returns 0 on success and 1 on error */
  623. static int extract_timestamp(const char *b, au_event_t *e)
  624. {
  625. char *ptr, *tmp;
  626. int rc = 1;
  627. e->host = NULL;
  628. tmp = strndupa(b, 80);
  629. ptr = strtok(tmp, " ");
  630. if (ptr) {
  631. // Optionally grab the node - may or may not be included
  632. if (*ptr == 'n') {
  633. e->host = strdup(ptr+5);
  634. ptr = strtok(NULL, " "); // Bump along to the next one
  635. }
  636. // at this point we have type=
  637. ptr = strtok(NULL, " ");
  638. if (ptr) {
  639. if (*(ptr+9) == '(')
  640. ptr+=9;
  641. else
  642. ptr = strchr(ptr, '(');
  643. if (ptr) {
  644. // now we should be pointed at the timestamp
  645. char *eptr;
  646. ptr++;
  647. eptr = strchr(ptr, ')');
  648. if (eptr)
  649. *eptr = 0;
  650. if (str2event(ptr, e) == 0)
  651. rc = 0;
  652. // else {
  653. // audit_msg(LOG_ERROR,
  654. // "Error extracting time stamp (%s)\n",
  655. // ptr);
  656. // }
  657. }
  658. // else we have a bad line
  659. }
  660. // else we have a bad line
  661. }
  662. // else we have a bad line
  663. return rc;
  664. }
  665. static int inline events_are_equal(au_event_t *e1, au_event_t *e2)
  666. {
  667. // Check time & serial first since its most likely way
  668. // to spot 2 different events
  669. if (!(e1->serial == e2->serial && e1->milli == e2->milli &&
  670. e1->sec == e2->sec))
  671. return 0;
  672. // Hmm...same so far, check if both have a host, only a string
  673. // compare can tell if they are the same. Otherwise, if only one
  674. // of them have a host, they are definitely not the same. Its
  675. // a boundary on daemon config.
  676. if (e1->host && e2->host) {
  677. if (strcmp(e1->host, e2->host))
  678. return 0;
  679. } else if (e1->host || e2->host)
  680. return 0;
  681. return 1;
  682. }
  683. /* This function will figure out how to get the next line of input.
  684. * storing it cur_buf. cur_buf will be NULL terminated but will not
  685. * contain a trailing newline. This implies a successful read
  686. * (result == 1) may result in a zero length cur_buf if a blank line
  687. * was read.
  688. *
  689. * cur_buf will have been allocated with malloc. The next time this
  690. * routine is called if cur_buf is non-NULL cur_buf will be freed,
  691. * thus if the caller wishes to retain a reference to malloc'ed
  692. * cur_buf data it should copy the cur_buf pointer and set cur_buf to
  693. * NULL.
  694. *
  695. * Returns:
  696. * 1 if successful (errno == 0)
  697. * 0 if non-blocking input unavailable (errno == 0)
  698. * -1 if error (errno contains non-zero error code)
  699. * -2 if EOF (errno == 0)
  700. */
  701. static int retrieve_next_line(auparse_state_t *au)
  702. {
  703. int rc;
  704. // If line was pushed back for re-reading return that
  705. if (au->line_pushed) {
  706. // Starting new event, clear previous event data,
  707. // previous line is returned again for new parsing
  708. au->line_pushed = 0;
  709. au->line_number++;
  710. return 1;
  711. }
  712. switch (au->source)
  713. {
  714. case AUSOURCE_DESCRIPTOR:
  715. case AUSOURCE_FILE_POINTER:
  716. rc = readline_file(au);
  717. if (rc > 0) au->line_number++;
  718. return rc;
  719. case AUSOURCE_LOGS:
  720. case AUSOURCE_FILE:
  721. case AUSOURCE_FILE_ARRAY:
  722. // if the first time through, open file
  723. if (au->list_idx == 0 && au->in == NULL) {
  724. au->line_number = 0;
  725. au->in = fopen(au->source_list[au->list_idx],
  726. "r");
  727. if (au->in == NULL)
  728. return -1;
  729. __fsetlocking(au->in, FSETLOCKING_BYCALLER);
  730. }
  731. // loop reading lines from a file
  732. while (au->in) {
  733. if ((rc = readline_file(au)) == -2) {
  734. // end of file, open next file,
  735. // try readline again
  736. fclose(au->in);
  737. au->in = NULL;
  738. au->list_idx++;
  739. au->line_number = 0;
  740. if (au->source_list[au->list_idx]) {
  741. au->in = fopen(
  742. au->source_list[au->list_idx],
  743. "r");
  744. if (au->in == NULL)
  745. return -1;
  746. __fsetlocking(au->in,
  747. FSETLOCKING_BYCALLER);
  748. }
  749. } else {
  750. if (rc > 0)
  751. au->line_number++;
  752. return rc;
  753. }
  754. }
  755. return -2; // return EOF
  756. case AUSOURCE_BUFFER:
  757. case AUSOURCE_BUFFER_ARRAY:
  758. rc = readline_buf(au);
  759. if (rc > 0)
  760. au->line_number++;
  761. return rc;
  762. case AUSOURCE_FEED:
  763. rc = readline_buf(au);
  764. // No such thing as EOF for feed, translate EOF
  765. // to data not available
  766. if (rc == -2)
  767. return 0;
  768. else
  769. if (rc > 0)
  770. au->line_number++;
  771. return rc;
  772. default:
  773. return -1;
  774. }
  775. return -1; /* should never reach here */
  776. }
  777. static void push_line(auparse_state_t *au)
  778. {
  779. au->line_number--;
  780. au->line_pushed = 1;
  781. }
  782. /*******
  783. * Functions that traverse events.
  784. ********/
  785. static int ausearch_reposition_cursors(auparse_state_t *au)
  786. {
  787. int rc = 0;
  788. switch (au->search_where)
  789. {
  790. case AUSEARCH_STOP_EVENT:
  791. aup_list_first(&au->le);
  792. aup_list_first_field(&au->le);
  793. break;
  794. case AUSEARCH_STOP_RECORD:
  795. aup_list_first_field(&au->le);
  796. break;
  797. case AUSEARCH_STOP_FIELD:
  798. // do nothing - this is the normal stopping point
  799. break;
  800. default:
  801. rc = -1;
  802. break;
  803. }
  804. return rc;
  805. }
  806. /* This is called during search once per each record. It walks the list
  807. * of nvpairs and decides if a field matches. */
  808. static int ausearch_compare(auparse_state_t *au)
  809. {
  810. rnode *r;
  811. if (au->regex_valid != 0) {
  812. int rc;
  813. r = aup_list_get_cur(&au->le);
  814. rc = regexec(&au->regex, r->record, 0, NULL, 0);
  815. if (rc == 0)
  816. return 1;
  817. else
  818. return 0;
  819. }
  820. r = aup_list_get_cur(&au->le);
  821. if (r)
  822. return expr_eval(au, r, au->expr);
  823. return 0;
  824. }
  825. // Returns < 0 on error, 0 no data, > 0 success
  826. int ausearch_next_event(auparse_state_t *au)
  827. {
  828. int rc;
  829. if (au->expr == NULL && au->regex_valid == 0) {
  830. errno = EINVAL;
  831. return -1;
  832. }
  833. if ((rc = auparse_first_record(au)) <= 0)
  834. return rc;
  835. do {
  836. do {
  837. if ((rc = ausearch_compare(au)) > 0) {
  838. ausearch_reposition_cursors(au);
  839. return 1;
  840. } else if (rc < 0)
  841. return rc;
  842. } while ((rc = auparse_next_record(au)) > 0);
  843. if (rc < 0)
  844. return rc;
  845. } while ((rc = auparse_next_event(au)) > 0);
  846. if (rc < 0)
  847. return rc;
  848. return 0;
  849. }
  850. // Brute force go to next event. Returns < 0 on error, 0 no data, > 0 success
  851. int auparse_next_event(auparse_state_t *au)
  852. {
  853. int rc;
  854. au_event_t event;
  855. if (au->parse_state == EVENT_EMITTED) {
  856. // If the last call resulted in emitting event data then
  857. // clear previous event data in preparation to accumulate
  858. // new event data
  859. aup_list_clear(&au->le);
  860. au->parse_state = EVENT_EMPTY;
  861. }
  862. // accumulate new event data
  863. while (1) {
  864. rc = retrieve_next_line(au);
  865. if (debug) printf("next_line(%d) '%s'\n", rc, au->cur_buf);
  866. if (rc == 0) return 0; // No data now
  867. if (rc == -2) {
  868. // We're at EOF, did we read any data previously?
  869. // If so return data available, else return no data
  870. // available
  871. if (au->parse_state == EVENT_ACCUMULATING) {
  872. if (debug) printf("EOF, EVENT_EMITTED\n");
  873. au->parse_state = EVENT_EMITTED;
  874. return 1; // data is available
  875. }
  876. return 0;
  877. }
  878. if (rc > 0) { // Input available
  879. rnode *r;
  880. if (extract_timestamp(au->cur_buf, &event)) {
  881. if (debug)
  882. printf("Malformed line:%s\n",
  883. au->cur_buf);
  884. continue;
  885. }
  886. if (au->parse_state == EVENT_EMPTY) {
  887. // First record in new event, initialize event
  888. if (debug)
  889. printf(
  890. "First record in new event, initialize event\n");
  891. aup_list_set_event(&au->le, &event);
  892. aup_list_append(&au->le, au->cur_buf,
  893. au->list_idx, au->line_number);
  894. au->parse_state = EVENT_ACCUMULATING;
  895. au->cur_buf = NULL;
  896. } else if (events_are_equal(&au->le.e, &event)) {
  897. // Accumulate data into existing event
  898. if (debug)
  899. printf(
  900. "Accumulate data into existing event\n");
  901. aup_list_append(&au->le, au->cur_buf,
  902. au->list_idx, au->line_number);
  903. au->parse_state = EVENT_ACCUMULATING;
  904. au->cur_buf = NULL;
  905. } else {
  906. // New event, save input for next invocation
  907. if (debug)
  908. printf(
  909. "New event, save current input for next invocation, EVENT_EMITTED\n");
  910. push_line(au);
  911. // Emit the event, set event cursors to
  912. // initial position
  913. aup_list_first(&au->le);
  914. aup_list_first_field(&au->le);
  915. au->parse_state = EVENT_EMITTED;
  916. free((char *)event.host);
  917. return 1; // data is available
  918. }
  919. free((char *)event.host);
  920. // Check to see if the event can be emitted due to EOE
  921. // or something we know is a single record event. At
  922. // this point, new record should be pointed at 'cur'
  923. if ((r = aup_list_get_cur(&au->le)) == NULL)
  924. continue;
  925. if ( r->type == AUDIT_EOE ||
  926. r->type < AUDIT_FIRST_EVENT ||
  927. r->type >= AUDIT_FIRST_ANOM_MSG) {
  928. // Emit the event, set event cursors to
  929. // initial position
  930. aup_list_first(&au->le);
  931. aup_list_first_field(&au->le);
  932. au->parse_state = EVENT_EMITTED;
  933. return 1; // data is available
  934. }
  935. } else { // Read error
  936. return -1;
  937. }
  938. }
  939. }
  940. hidden_def(auparse_next_event)
  941. /* Accessors to event data */
  942. const au_event_t *auparse_get_timestamp(auparse_state_t *au)
  943. {
  944. if (au && au->le.e.sec != 0)
  945. return &au->le.e;
  946. else
  947. return NULL;
  948. }
  949. time_t auparse_get_time(auparse_state_t *au)
  950. {
  951. if (au)
  952. return au->le.e.sec;
  953. else
  954. return 0;
  955. }
  956. unsigned int auparse_get_milli(auparse_state_t *au)
  957. {
  958. if (au)
  959. return au->le.e.milli;
  960. else
  961. return 0;
  962. }
  963. unsigned long auparse_get_serial(auparse_state_t *au)
  964. {
  965. if (au)
  966. return au->le.e.serial;
  967. else
  968. return 0;
  969. }
  970. // Gets the machine node name
  971. const char *auparse_get_node(auparse_state_t *au)
  972. {
  973. if (au && au->le.e.host != NULL)
  974. return strdup(au->le.e.host);
  975. else
  976. return NULL;
  977. }
  978. int auparse_node_compare(au_event_t *e1, au_event_t *e2)
  979. {
  980. // If both have a host, only a string compare can tell if they
  981. // are the same. Otherwise, if only one of them have a host, they
  982. // are definitely not the same. Its a boundary on daemon config.
  983. if (e1->host && e2->host)
  984. return strcmp(e1->host, e2->host);
  985. else if (e1->host)
  986. return 1;
  987. else if (e2->host)
  988. return -1;
  989. return 0;
  990. }
  991. int auparse_timestamp_compare(au_event_t *e1, au_event_t *e2)
  992. {
  993. if (e1->sec > e2->sec)
  994. return 1;
  995. if (e1->sec < e2->sec)
  996. return -1;
  997. if (e1->milli > e2->milli)
  998. return 1;
  999. if (e1->milli < e2->milli)
  1000. return -1;
  1001. if (e1->serial > e2->serial)
  1002. return 1;
  1003. if (e1->serial < e2->serial)
  1004. return -1;
  1005. return 0;
  1006. }
  1007. unsigned int auparse_get_num_records(auparse_state_t *au)
  1008. {
  1009. return aup_list_get_cnt(&au->le);
  1010. }
  1011. /* Functions that traverse records in the same event */
  1012. int auparse_first_record(auparse_state_t *au)
  1013. {
  1014. int rc;
  1015. if (aup_list_get_cnt(&au->le) == 0) {
  1016. rc = auparse_next_event(au);
  1017. if (rc <= 0)
  1018. return rc;
  1019. }
  1020. aup_list_first(&au->le);
  1021. aup_list_first_field(&au->le);
  1022. return 1;
  1023. }
  1024. hidden_def(auparse_first_record)
  1025. int auparse_next_record(auparse_state_t *au)
  1026. {
  1027. if (aup_list_get_cnt(&au->le) == 0) {
  1028. int rc = auparse_first_record(au);
  1029. if (rc <= 0)
  1030. return rc;
  1031. }
  1032. if (aup_list_next(&au->le))
  1033. return 1;
  1034. else
  1035. return 0;
  1036. }
  1037. hidden_def(auparse_next_record)
  1038. int auparse_goto_record_num(auparse_state_t *au, unsigned int num)
  1039. {
  1040. /* Check if a request is out of range */
  1041. if (num >= aup_list_get_cnt(&au->le))
  1042. return 0;
  1043. if (aup_list_goto_rec(&au->le, num) != NULL)
  1044. return 1;
  1045. else
  1046. return 0;
  1047. }
  1048. /* Accessors to record data */
  1049. int auparse_get_type(auparse_state_t *au)
  1050. {
  1051. rnode *r = aup_list_get_cur(&au->le);
  1052. if (r)
  1053. return r->type;
  1054. else
  1055. return 0;
  1056. }
  1057. unsigned int auparse_get_line_number(auparse_state_t *au)
  1058. {
  1059. rnode *r = aup_list_get_cur(&au->le);
  1060. if (r)
  1061. return r->line_number;
  1062. else
  1063. return 0;
  1064. }
  1065. const char *auparse_get_filename(auparse_state_t *au)
  1066. {
  1067. switch (au->source)
  1068. {
  1069. case AUSOURCE_FILE:
  1070. case AUSOURCE_FILE_ARRAY:
  1071. break;
  1072. default:
  1073. return NULL;
  1074. }
  1075. rnode *r = aup_list_get_cur(&au->le);
  1076. if (r) {
  1077. if (r->list_idx < 0) return NULL;
  1078. return au->source_list[r->list_idx];
  1079. } else {
  1080. return NULL;
  1081. }
  1082. }
  1083. int auparse_first_field(auparse_state_t *au)
  1084. {
  1085. return aup_list_first_field(&au->le);
  1086. }
  1087. int auparse_next_field(auparse_state_t *au)
  1088. {
  1089. rnode *r = aup_list_get_cur(&au->le);
  1090. if (r) {
  1091. if (nvlist_next(&r->nv))
  1092. return 1;
  1093. else
  1094. return 0;
  1095. }
  1096. return 0;
  1097. }
  1098. unsigned int auparse_get_num_fields(auparse_state_t *au)
  1099. {
  1100. rnode *r = aup_list_get_cur(&au->le);
  1101. if (r)
  1102. return nvlist_get_cnt(&r->nv);
  1103. else
  1104. return 0;
  1105. }
  1106. const char *auparse_get_record_text(auparse_state_t *au)
  1107. {
  1108. rnode *r = aup_list_get_cur(&au->le);
  1109. if (r)
  1110. return r->record;
  1111. else
  1112. return NULL;
  1113. }
  1114. /* scan from current location to end of event */
  1115. const char *auparse_find_field(auparse_state_t *au, const char *name)
  1116. {
  1117. free(au->find_field);
  1118. au->find_field = strdup(name);
  1119. if (au->le.e.sec) {
  1120. const char *cur_name;
  1121. rnode *r;
  1122. // look at current record before moving
  1123. r = aup_list_get_cur(&au->le);
  1124. if (r == NULL)
  1125. return NULL;
  1126. cur_name = nvlist_get_cur_name(&r->nv);
  1127. if (cur_name && strcmp(cur_name, name) == 0)
  1128. return nvlist_get_cur_val(&r->nv);
  1129. return auparse_find_field_next(au);
  1130. }
  1131. return NULL;
  1132. }
  1133. /* Increment 1 location and then scan for next field */
  1134. const char *auparse_find_field_next(auparse_state_t *au)
  1135. {
  1136. if (au->find_field == NULL) {
  1137. errno = EINVAL;
  1138. return NULL;
  1139. }
  1140. if (au->le.e.sec) {
  1141. int moved = 0;
  1142. rnode *r = aup_list_get_cur(&au->le);
  1143. while (r) { // For each record in the event...
  1144. if (!moved) {
  1145. nvlist_next(&r->nv);
  1146. moved=1;
  1147. }
  1148. if (nvlist_find_name(&r->nv, au->find_field))
  1149. return nvlist_get_cur_val(&r->nv);
  1150. r = aup_list_next(&au->le);
  1151. if (r)
  1152. aup_list_first_field(&au->le);
  1153. }
  1154. }
  1155. return NULL;
  1156. }
  1157. hidden_def(auparse_find_field_next)
  1158. /* Accessors to field data */
  1159. const char *auparse_get_field_name(auparse_state_t *au)
  1160. {
  1161. if (au->le.e.sec) {
  1162. rnode *r = aup_list_get_cur(&au->le);
  1163. if (r)
  1164. return nvlist_get_cur_name(&r->nv);
  1165. }
  1166. return NULL;
  1167. }
  1168. const char *auparse_get_field_str(auparse_state_t *au)
  1169. {
  1170. if (au->le.e.sec) {
  1171. rnode *r = aup_list_get_cur(&au->le);
  1172. if (r)
  1173. return nvlist_get_cur_val(&r->nv);
  1174. }
  1175. return NULL;
  1176. }
  1177. hidden_def(auparse_get_field_str)
  1178. int auparse_get_field_type(auparse_state_t *au)
  1179. {
  1180. if (au->le.e.sec) {
  1181. rnode *r = aup_list_get_cur(&au->le);
  1182. if (r)
  1183. return nvlist_get_cur_type(r);
  1184. }
  1185. return AUPARSE_TYPE_UNCLASSIFIED;
  1186. }
  1187. int auparse_get_field_int(auparse_state_t *au)
  1188. {
  1189. const char *v = auparse_get_field_str(au);
  1190. if (v) {
  1191. int val;
  1192. errno = 0;
  1193. val = strtol(v, NULL, 10);
  1194. if (errno == 0)
  1195. return val;
  1196. } else
  1197. errno = ENODATA;
  1198. return -1;
  1199. }
  1200. const char *auparse_interpret_field(auparse_state_t *au)
  1201. {
  1202. if (au->le.e.sec) {
  1203. rnode *r = aup_list_get_cur(&au->le);
  1204. if (r)
  1205. return nvlist_interp_cur_val(r);
  1206. }
  1207. return NULL;
  1208. }