static int match_expr (struct bt_node *expr, const char *key) { int retval = 1; int i; if (expr) { if (!expr->left && !expr->right) { for (i = 0; i < 4; i++) { if (expr->data[i] != '?' && expr->data[i] != key[i]) { retval = 0; break; } } } else { if (expr->left) { retval = match_expr(expr->left, key); } if (expr->right) { if (retval && (expr->flag & FLAG_AND)) /* and */ retval &= match_expr(expr->right, key); else if (!retval && !(expr->flag & FLAG_AND)) /* or */ retval = match_expr(expr->right, key); } } if (expr->flag & FLAG_NOT) /* not */ retval = retval ? 0 : 1; } return retval; }
static int match_expr(struct search_node *head, struct log_info *log) { struct search_node *sn; int matched = 1, rc; for (sn = head; sn; sn = sn->next) { /* If we have no match, skip ahead to the next OR entry. */ if (!matched && !sn->or) continue; switch (sn->type) { case ST_EXPR: matched = match_expr(sn->u.expr, log); break; case ST_CWD: matched = strcmp(sn->u.cwd, log->cwd) == 0; break; case ST_TTY: matched = strcmp(sn->u.tty, log->tty) == 0; break; case ST_RUNASGROUP: matched = strcmp(sn->u.runas_group, log->runas_group) == 0; break; case ST_RUNASUSER: matched = strcmp(sn->u.runas_user, log->runas_user) == 0; break; case ST_USER: matched = strcmp(sn->u.user, log->user) == 0; break; case ST_PATTERN: #ifdef HAVE_REGCOMP rc = regexec(&sn->u.cmdre, log->cmd, 0, NULL, 0); if (rc && rc != REG_NOMATCH) { char buf[BUFSIZ]; regerror(rc, &sn->u.cmdre, buf, sizeof(buf)); errorx(1, "%s", buf); } matched = rc == REG_NOMATCH ? 0 : 1; #else matched = strstr(log.cmd, sn->u.pattern) != NULL; #endif break; case ST_FROMDATE: matched = log->tstamp >= sn->u.tstamp; break; case ST_TODATE: matched = log->tstamp <= sn->u.tstamp; break; } if (sn->negated) matched = !matched; } return matched; }
static int match_line(struct grep_opt *opt, char *bol, char *eol, enum grep_context ctx, int collect_hits) { struct grep_pat *p; if (opt->extended) return match_expr(opt, bol, eol, ctx, collect_hits); /* we do not call with collect_hits without being extended */ for (p = opt->pattern_list; p; p = p->next) { if (match_one_pattern(opt, p, bol, eol, ctx)) return 1; } return 0; }
static int list_session_dir(char *pathbuf, REGEX_T *re, const char *user, const char *tty) { FILE *fp; DIR *d; struct dirent *dp; char *buf = NULL, *cmd = NULL, *cwd = NULL, idstr[7], *cp; struct log_info li; size_t bufsize = 0, cwdsize = 0, cmdsize = 0, plen; plen = strlen(pathbuf); d = opendir(pathbuf); if (d == NULL && errno != ENOTDIR) { warning("cannot opendir %s", pathbuf); return -1; } while ((dp = readdir(d)) != NULL) { if (NAMLEN(dp) != 2 || !isalnum((unsigned char)dp->d_name[0]) || !isalnum((unsigned char)dp->d_name[1])) continue; /* open log file, print id and command */ pathbuf[plen + 0] = '/'; pathbuf[plen + 1] = dp->d_name[0]; pathbuf[plen + 2] = dp->d_name[1]; pathbuf[plen + 3] = '/'; pathbuf[plen + 4] = 'l'; pathbuf[plen + 5] = 'o'; pathbuf[plen + 6] = 'g'; pathbuf[plen + 7] = '\0'; fp = fopen(pathbuf, "r"); if (fp == NULL) { warning("unable to open %s", pathbuf); continue; } /* * ID file has three lines: * 1) a log info line * 2) cwd * 3) command with args */ if (getline(&buf, &bufsize, fp) == -1 || getline(&cwd, &cwdsize, fp) == -1 || getline(&cmd, &cmdsize, fp) == -1) { fclose(fp); continue; } fclose(fp); /* crack the log line: timestamp:user:runas_user:runas_group:tty */ buf[strcspn(buf, "\n")] = '\0'; if ((li.tstamp = atoi(buf)) == 0) continue; if ((cp = strchr(buf, ':')) == NULL) continue; *cp++ = '\0'; li.user = cp; if ((cp = strchr(cp, ':')) == NULL) continue; *cp++ = '\0'; li.runas_user = cp; if ((cp = strchr(cp, ':')) == NULL) continue; *cp++ = '\0'; li.runas_group = cp; if ((cp = strchr(cp, ':')) == NULL) continue; *cp++ = '\0'; li.tty = cp; cwd[strcspn(cwd, "\n")] = '\0'; li.cwd = cwd; cmd[strcspn(cmd, "\n")] = '\0'; li.cmd = cmd; /* Match on search expression if there is one. */ if (search_expr && !match_expr(search_expr, &li)) continue; /* Convert from /var/log/sudo-sessions/00/00/01 to 000001 */ idstr[0] = pathbuf[plen - 5]; idstr[1] = pathbuf[plen - 4]; idstr[2] = pathbuf[plen - 2]; idstr[3] = pathbuf[plen - 1]; idstr[4] = pathbuf[plen + 1]; idstr[5] = pathbuf[plen + 2]; idstr[6] = '\0'; printf("%s : %s : TTY=%s ; CWD=%s ; USER=%s ; ", get_timestr(li.tstamp, 1), li.user, li.tty, li.cwd, li.runas_user); if (*li.runas_group) printf("GROUP=%s ; ", li.runas_group); printf("TSID=%s ; COMMAND=%s\n", idstr, li.cmd); } return 0; }