2 * Copyright 2004-2009,2012,2014 Red Hat Inc., Durham, North Carolina.
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.
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.
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
20 * Steve Grubb <sgrubb@redhat.com>
21 * Rickard E. (Rik) Faith <faith@redhat.com>
36 #include <sys/utsname.h>
38 #include <fcntl.h> /* O_NOFOLLOW needs gnu defined */
39 #include <limits.h> /* for PATH_MAX */
41 #include <sys/types.h>
47 /* #defines for the audit failure query */
48 #define CONFIG_FILE "/etc/libaudit.conf"
50 /* Local prototypes */
60 int (*parser)(const char *, int);
71 auditfail_t failure_action;
74 static const struct nv_list failure_actions[] =
76 {"ignore", FAIL_IGNORE },
78 {"terminate", FAIL_TERMINATE },
82 int _audit_permadded = 0;
83 int _audit_archadded = 0;
84 int _audit_syscalladded = 0;
85 unsigned int _audit_elf = 0U;
86 static struct libaudit_conf config;
88 static int audit_failure_parser(const char *val, int line);
89 static int audit_name_to_uid(const char *name, uid_t *uid);
90 static int audit_name_to_gid(const char *name, gid_t *gid);
92 static const struct kw_pair keywords[] =
94 {"failure_action", audit_failure_parser },
98 static int audit_priority(int xerrno)
100 /* If they've compiled their own kernel and did not include
101 * the audit susbsystem, they will get ECONNREFUSED. We'll
102 * demote the message to debug so its not lost entirely. */
103 if (xerrno == ECONNREFUSED)
109 int audit_request_status(int fd)
111 int rc = audit_send(fd, AUDIT_GET, NULL, 0);
113 audit_msg(audit_priority(errno),
114 "Error sending status request (%s)", strerror(-rc));
117 hidden_def(audit_request_status)
120 * Set everything to its default value
122 static void clear_config(void)
124 config.failure_action = FAIL_IGNORE;
127 /* Get 1 line from file */
128 static char *get_line(FILE *f, char *buf, size_t len)
130 if (fgets(buf, len, f)) {
132 char *ptr = strchr(buf, 0x0a);
140 static int nv_split(char *buf, struct nv_pair *nv)
142 /* Get the name part */
143 char *ptr, *saved=NULL;
147 ptr = audit_strsplit_r(buf, &saved);
149 return 0; /* If there's nothing, go to next line */
151 return 0; /* If there's a comment, go to next line */
154 /* Check for a '=' */
155 ptr = audit_strsplit_r(NULL, &saved);
158 if (strcmp(ptr, "=") != 0)
162 ptr = audit_strsplit_r(NULL, &saved);
167 /* Make sure there's nothing else */
168 ptr = audit_strsplit_r(NULL, &saved);
172 /* Everything is OK */
176 static const struct kw_pair *kw_lookup(const char *val)
179 while (keywords[i].name != NULL) {
180 if (strcasecmp(keywords[i].name, val) == 0)
187 static int audit_failure_parser(const char *val, int line)
191 audit_msg(LOG_DEBUG, "audit_failure_parser called with: %s", val);
192 for (i=0; failure_actions[i].name != NULL; i++) {
193 if (strcasecmp(val, failure_actions[i].name) == 0) {
194 config.failure_action = failure_actions[i].option;
198 audit_msg(LOG_ERR, "Option %s not found - line %d", val, line);
203 * Read the /etc/libaudit.conf file and all tunables.
205 static int load_libaudit_config(const char *path)
207 int fd, rc, lineno = 1;
213 rc = open(path, O_NOFOLLOW|O_RDONLY);
215 if (errno != ENOENT) {
216 audit_msg(LOG_ERR, "Error opening %s (%s)",
217 path, strerror(errno));
220 audit_msg(LOG_WARNING,
221 "Config file %s doesn't exist, skipping", path);
226 /* check the file's permissions: owned by root, not world writable,
229 audit_msg(LOG_DEBUG, "Config file %s opened for parsing", path);
230 if (fstat(fd, &st) < 0) {
231 audit_msg(LOG_ERR, "Error fstat'ing %s (%s)",
232 path, strerror(errno));
236 if (st.st_uid != 0) {
237 audit_msg(LOG_ERR, "Error - %s isn't owned by root", path);
241 if ((st.st_mode & S_IWOTH) == S_IWOTH) {
242 audit_msg(LOG_ERR, "Error - %s is world writable", path);
246 if (!S_ISREG(st.st_mode)) {
247 audit_msg(LOG_ERR, "Error - %s is not a regular file", path);
252 /* it's ok, read line by line */
253 f = fdopen(fd, "rm");
255 audit_msg(LOG_ERR, "Error - fdopen failed (%s)",
261 while (get_line(f, buf, sizeof(buf))) {
262 // convert line into name-value pair
263 const struct kw_pair *kw;
265 rc = nv_split(buf, &nv);
269 case 1: // not the right number of tokens.
271 "Wrong number of arguments for line %d in %s",
274 case 2: // no '=' sign
276 "Missing equal sign for line %d in %s",
279 default: // something else went wrong...
281 "Unknown error for line %d in %s",
285 if (nv.name == NULL) {
289 if (nv.value == NULL) {
294 /* identify keyword or error */
295 kw = kw_lookup(nv.name);
296 if (kw->name == NULL) {
298 "Unknown keyword \"%s\" in line %d of %s",
299 nv.name, lineno, path);
304 /* dispatch to keyword's local parser */
305 rc = kw->parser(nv.value, lineno);
308 return 1; // local parser puts message out
320 * This function is called to get the value of the failure_action
321 * tunable stored in /etc/libaudit.conf. The function returns 1 if
322 * the tunable is not found or there is an error. If the tunable is found,
323 * 0 is returned the the tunable value is saved in the failmode parameter.
325 int get_auditfail_action(auditfail_t *failmode)
329 if (load_libaudit_config(CONFIG_FILE)) {
330 *failmode = config.failure_action;
334 *failmode = config.failure_action;
338 int audit_set_enabled(int fd, uint32_t enabled)
341 struct audit_status s;
343 memset(&s, 0, sizeof(s));
344 s.mask = AUDIT_STATUS_ENABLED;
346 rc = audit_send(fd, AUDIT_SET, &s, sizeof(s));
348 audit_msg(audit_priority(errno),
349 "Error sending enable request (%s)", strerror(-rc));
354 * This function will return 0 if auditing is NOT enabled and
355 * 1 if enabled, and -1 on error.
357 int audit_is_enabled(int fd)
364 if ((rc = audit_request_status(fd)) > 0) {
365 struct audit_reply rep;
367 int timeout = 40; /* tenths of seconds */
368 struct pollfd pfd[1];
371 pfd[0].events = POLLIN;
373 for (i = 0; i < timeout; i++) {
375 rc = poll(pfd, 1, 100);
376 } while (rc < 0 && errno == EINTR);
378 rc = audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING,0);
380 /* If we get done or error, break out */
381 if (rep.type == NLMSG_DONE ||
382 rep.type == NLMSG_ERROR)
385 /* If its not status, keep looping */
386 if (rep.type != AUDIT_GET)
390 return rep.status->enabled;
394 if (rc == -ECONNREFUSED) {
395 /* This is here to let people that build their own kernel
396 and disable the audit system get in. ECONNREFUSED is
397 issued by the kernel when there is "no on listening". */
399 } else if (rc == -EPERM && getuid() != 0) {
400 /* If we get this, then the kernel supports auditing
401 * but we don't have enough privilege to write to the
402 * socket. Therefore, we have already been authenticated
403 * and we are a common user. Just act as though auditing
404 * is not enabled. Any other error we take seriously.
405 * This is here basically to satisfy Xscreensaver. */
411 int audit_set_failure(int fd, uint32_t failure)
414 struct audit_status s;
416 memset(&s, 0, sizeof(s));
417 s.mask = AUDIT_STATUS_FAILURE;
419 rc = audit_send(fd, AUDIT_SET, &s, sizeof(s));
421 audit_msg(audit_priority(errno),
422 "Error sending failure mode request (%s)",
428 * This function returns -1 on error and 1 on success.
430 int audit_set_pid(int fd, uint32_t pid, rep_wait_t wmode)
432 struct audit_status s;
433 struct audit_reply rep;
434 struct pollfd pfd[1];
437 memset(&s, 0, sizeof(s));
438 s.mask = AUDIT_STATUS_PID;
440 rc = audit_send(fd, AUDIT_SET, &s, sizeof(s));
442 audit_msg(audit_priority(errno),
443 "Error setting audit daemon pid (%s)",
447 if (wmode == WAIT_NO)
450 /* Now we'll see if there's any reply message. This only
451 happens on error. It is not fatal if there is no message.
452 As a matter of fact, we don't do anything with the message
453 besides gobble it. */
455 pfd[0].events = POLLIN;
457 rc = poll(pfd, 1, 100); /* .1 second */
458 } while (rc < 0 && errno == EINTR);
460 (void)audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0);
464 int audit_set_rate_limit(int fd, uint32_t limit)
467 struct audit_status s;
469 memset(&s, 0, sizeof(s));
470 s.mask = AUDIT_STATUS_RATE_LIMIT;
471 s.rate_limit = limit;
472 rc = audit_send(fd, AUDIT_SET, &s, sizeof(s));
474 audit_msg(audit_priority(errno),
475 "Error sending rate limit request (%s)",
480 int audit_set_backlog_limit(int fd, uint32_t limit)
483 struct audit_status s;
485 memset(&s, 0, sizeof(s));
486 s.mask = AUDIT_STATUS_BACKLOG_LIMIT;
487 s.backlog_limit = limit;
488 rc = audit_send(fd, AUDIT_SET, &s, sizeof(s));
490 audit_msg(audit_priority(errno),
491 "Error sending backlog limit request (%s)",
496 int audit_set_backlog_wait_time(int fd, uint32_t bwt)
499 #if HAVE_DECL_AUDIT_VERSION_BACKLOG_WAIT_TIME
500 struct audit_status s;
502 memset(&s, 0, sizeof(s));
503 s.mask = AUDIT_STATUS_BACKLOG_WAIT_TIME;
504 s.backlog_wait_time = bwt;
505 rc = audit_send(fd, AUDIT_SET, &s, sizeof(s));
507 audit_msg(audit_priority(errno),
508 "Error sending backlog limit request (%s)",
514 int audit_set_feature(int fd, unsigned feature, unsigned value, unsigned lock)
516 #if HAVE_DECL_AUDIT_FEATURE_VERSION
518 struct audit_features f;
520 memset(&f, 0, sizeof(f));
521 f.mask = AUDIT_FEATURE_TO_MASK(feature);
523 f.features = AUDIT_FEATURE_TO_MASK(feature);
525 f.lock = AUDIT_FEATURE_TO_MASK(feature);
526 rc = audit_send(fd, AUDIT_SET_FEATURE, &f, sizeof(f));
528 audit_msg(audit_priority(errno),
529 "Error setting feature (%s)",
537 hidden_def(audit_set_feature)
539 int audit_request_features(int fd)
541 #if HAVE_DECL_AUDIT_FEATURE_VERSION
543 struct audit_features f;
545 memset(&f, 0, sizeof(f));
546 rc = audit_send(fd, AUDIT_GET_FEATURE, &f, sizeof(f));
548 audit_msg(audit_priority(errno),
549 "Error getting feature (%s)",
557 hidden_def(audit_request_features)
559 extern int audit_set_loginuid_immutable(int fd)
561 #if HAVE_DECL_AUDIT_FEATURE_VERSION
562 return audit_set_feature(fd, AUDIT_FEATURE_LOGINUID_IMMUTABLE, 1, 1);
569 int audit_request_rules_list_data(int fd)
571 int rc = audit_send(fd, AUDIT_LIST_RULES, NULL, 0);
572 if (rc < 0 && rc != -EINVAL)
573 audit_msg(audit_priority(errno),
574 "Error sending rule list data request (%s)",
579 int audit_request_signal_info(int fd)
581 int rc = audit_send(fd, AUDIT_SIGNAL_INFO, NULL, 0);
583 audit_msg(LOG_WARNING,
584 "Error sending signal_info request (%s)",
589 int audit_update_watch_perms(struct audit_rule_data *rule, int perms)
593 if (rule->field_count < 1)
596 // First see if we have an entry we are updating
597 for (i=0; i< rule->field_count; i++) {
598 if (rule->fields[i] == AUDIT_PERM) {
599 rule->values[i] = perms;
604 // If not check to see if we have room to add a field
605 if (rule->field_count >= (AUDIT_MAX_FIELDS - 1))
609 rule->fields[rule->field_count] = AUDIT_PERM;
610 rule->fieldflags[rule->field_count] = AUDIT_EQUAL;
611 rule->values[rule->field_count] = perms;
617 int audit_add_watch(struct audit_rule_data **rulep, const char *path)
619 return audit_add_watch_dir(AUDIT_WATCH, rulep, path);
622 int audit_add_dir(struct audit_rule_data **rulep, const char *path)
624 return audit_add_watch_dir(AUDIT_DIR, rulep, path);
627 int audit_add_watch_dir(int type, struct audit_rule_data **rulep,
630 size_t len = strlen(path);
631 struct audit_rule_data *rule = *rulep;
633 if (rule && rule->field_count) {
634 audit_msg(LOG_ERR, "Rule is not empty\n");
637 if (type != AUDIT_WATCH && type != AUDIT_DIR) {
638 audit_msg(LOG_ERR, "Invalid type used\n");
642 *rulep = realloc(rule, len + sizeof(*rule));
643 if (*rulep == NULL) {
645 audit_msg(LOG_ERR, "Cannot realloc memory!\n");
649 memset(rule, 0, len + sizeof(*rule));
651 rule->flags = AUDIT_FILTER_EXIT;
652 rule->action = AUDIT_ALWAYS;
653 audit_rule_syscallbyname_data(rule, "all");
654 rule->field_count = 2;
655 rule->fields[0] = type;
656 rule->values[0] = len;
657 rule->fieldflags[0] = AUDIT_EQUAL;
659 memcpy(&rule->buf[0], path, len);
661 // Default to all permissions
662 rule->fields[1] = AUDIT_PERM;
663 rule->fieldflags[1] = AUDIT_EQUAL;
664 rule->values[1] = AUDIT_PERM_READ | AUDIT_PERM_WRITE |
665 AUDIT_PERM_EXEC | AUDIT_PERM_ATTR;
667 _audit_permadded = 1;
671 hidden_def(audit_add_watch_dir)
673 int audit_add_rule_data(int fd, struct audit_rule_data *rule,
674 int flags, int action)
678 if (flags == AUDIT_FILTER_ENTRY) {
679 audit_msg(LOG_WARNING, "Use of entry filter is deprecated");
683 rule->action = action;
684 rc = audit_send(fd, AUDIT_ADD_RULE, rule,
685 sizeof(struct audit_rule_data) + rule->buflen);
687 audit_msg(audit_priority(errno),
688 "Error sending add rule data request (%s)",
690 "Rule exists" : strerror(-rc));
694 int audit_delete_rule_data(int fd, struct audit_rule_data *rule,
695 int flags, int action)
699 if (flags == AUDIT_FILTER_ENTRY) {
700 audit_msg(LOG_WARNING, "Use of entry filter is deprecated");
704 rule->action = action;
705 rc = audit_send(fd, AUDIT_DEL_RULE, rule,
706 sizeof(struct audit_rule_data) + rule->buflen);
709 audit_msg(LOG_WARNING,
710 "Error sending delete rule request (No rule matches)");
712 audit_msg(audit_priority(errno),
713 "Error sending delete rule data request (%s)",
720 * This function is part of the directory auditing code
722 int audit_trim_subtrees(int fd)
724 int rc = audit_send(fd, AUDIT_TRIM, NULL, 0);
726 audit_msg(audit_priority(errno),
727 "Error sending trim subtrees command (%s)",
733 * This function is part of the directory auditing code
735 int audit_make_equivalent(int fd, const char *mount_point,
739 size_t len1 = strlen(mount_point);
740 size_t len2 = strlen(subtree);
744 } *cmd = malloc(sizeof(*cmd) + len1 + len2);
746 memset(cmd, 0, sizeof(*cmd) + len1 + len2);
748 cmd->sizes[0] = len1;
749 cmd->sizes[1] = len2;
750 memcpy(&cmd->buf[0], mount_point, len1);
751 memcpy(&cmd->buf[len1], subtree, len2);
753 rc = audit_send(fd, AUDIT_MAKE_EQUIV, cmd, sizeof(*cmd) + len1 + len2);
755 audit_msg(audit_priority(errno),
756 "Error sending make_equivalent command (%s)",
763 * This function will retreive the loginuid or -1 if there
766 uid_t audit_getloginuid(void)
773 in = open("/proc/self/loginuid", O_NOFOLLOW|O_RDONLY);
777 len = read(in, buf, sizeof(buf));
778 } while (len < 0 && errno == EINTR);
780 if (len < 0 || len >= sizeof(buf))
784 uid = strtol(buf, 0, 10);
792 * This function returns 0 on success and 1 on failure
794 int audit_setloginuid(uid_t uid)
797 int o, count, rc = 0;
800 count = snprintf(loginuid, sizeof(loginuid), "%u", uid);
801 o = open("/proc/self/loginuid", O_NOFOLLOW|O_WRONLY|O_TRUNC);
803 int block, offset = 0;
806 block = write(o, &loginuid[offset], (unsigned)count);
811 audit_msg(LOG_ERR, "Error writing loginuid");
820 audit_msg(LOG_ERR, "Error opening /proc/self/loginuid");
826 int audit_rule_syscall_data(struct audit_rule_data *rule, int scall)
828 int word = AUDIT_WORD(scall);
829 int bit = AUDIT_BIT(scall);
831 if (word >= (AUDIT_BITMASK_SIZE-1))
833 rule->mask[word] |= bit;
836 hidden_def(audit_rule_syscall_data)
838 int audit_rule_syscallbyname_data(struct audit_rule_data *rule,
844 if (!strcmp(scall, "all")) {
845 for (i = 0; i < (AUDIT_BITMASK_SIZE-1); i++)
850 machine = audit_detect_machine();
852 machine = audit_elf_to_machine(_audit_elf);
855 nr = audit_name_to_syscall(scall, machine);
857 if (isdigit(scall[0]))
858 nr = strtol(scall, NULL, 0);
861 return audit_rule_syscall_data(rule, nr);
864 hidden_def(audit_rule_syscallbyname_data)
866 int audit_rule_interfield_comp_data(struct audit_rule_data **rulep,
869 const char *f = pair;
873 struct audit_rule_data *rule = *rulep;
878 if (rule->field_count >= (AUDIT_MAX_FIELDS - 1))
881 /* look for 2-char operators first
882 then look for 1-char operators afterwards
883 when found, null out the bytes under the operators to split
884 and set value pointer just past operator bytes
886 if ( (v = strstr(pair, "!=")) ) {
889 op = AUDIT_NOT_EQUAL;
890 } else if ( (v = strstr(pair, "=")) ) {
903 if ((field1 = audit_name_to_field(f)) < 0)
906 if ((field2 = audit_name_to_field(v)) < 0)
909 /* Interfield comparison can only be in exit filter */
910 if (flags != AUDIT_FILTER_EXIT)
913 // It should always be AUDIT_FIELD_COMPARE
914 rule->fields[rule->field_count] = AUDIT_FIELD_COMPARE;
915 rule->fieldflags[rule->field_count] = op;
916 /* oh god, so many permutations */
923 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_EUID;
926 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_FSUID;
929 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_OBJ_UID;
932 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_SUID;
935 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_EUID;
944 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_FSUID;
947 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_FSUID;
950 rule->values[rule->field_count] = AUDIT_COMPARE_FSUID_TO_OBJ_UID;
953 rule->values[rule->field_count] = AUDIT_COMPARE_SUID_TO_FSUID;
956 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_FSUID;
965 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_EUID;
968 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_FSUID;
971 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_OBJ_UID;
974 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_SUID;
977 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_AUID;
986 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_SUID;
989 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_SUID;
992 rule->values[rule->field_count] = AUDIT_COMPARE_SUID_TO_FSUID;
995 rule->values[rule->field_count] = AUDIT_COMPARE_SUID_TO_OBJ_UID;
998 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_SUID;
1006 case AUDIT_LOGINUID:
1007 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_OBJ_UID;
1010 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_OBJ_UID;
1013 rule->values[rule->field_count] = AUDIT_COMPARE_FSUID_TO_OBJ_UID;
1016 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_OBJ_UID;
1019 rule->values[rule->field_count] = AUDIT_COMPARE_SUID_TO_OBJ_UID;
1027 case AUDIT_LOGINUID:
1028 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_AUID;
1031 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_EUID;
1034 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_FSUID;
1037 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_OBJ_UID;
1040 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_SUID;
1047 /* GID comparisons */
1051 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_FSGID;
1054 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_EGID;
1057 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_OBJ_GID;
1060 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_SGID;
1069 rule->values[rule->field_count] = AUDIT_COMPARE_SGID_TO_FSGID;
1072 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_FSGID;
1075 rule->values[rule->field_count] = AUDIT_COMPARE_FSGID_TO_OBJ_GID;
1078 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_FSGID;
1087 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_EGID;
1090 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_FSGID;
1093 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_OBJ_GID;
1096 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_SGID;
1105 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_OBJ_GID;
1108 rule->values[rule->field_count] = AUDIT_COMPARE_FSGID_TO_OBJ_GID;
1111 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_OBJ_GID;
1114 rule->values[rule->field_count] = AUDIT_COMPARE_SGID_TO_OBJ_GID;
1123 rule->values[rule->field_count] = AUDIT_COMPARE_SGID_TO_FSGID;
1126 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_SGID;
1129 rule->values[rule->field_count] = AUDIT_COMPARE_SGID_TO_OBJ_GID;
1132 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_SGID;
1142 rule->field_count++;
1146 int audit_determine_machine(const char *arch)
1147 { // What do we want? i686, x86_64, ia64 or b64, b32
1149 unsigned int bits = 0;
1151 if (strcasecmp("b64", arch) == 0) {
1152 bits = __AUDIT_ARCH_64BIT;
1153 machine = audit_detect_machine();
1154 } else if (strcasecmp("b32", arch) == 0) {
1155 bits = ~__AUDIT_ARCH_64BIT;
1156 machine = audit_detect_machine();
1158 machine = audit_name_to_machine(arch);
1160 // See if its numeric
1163 ival = strtoul(arch, NULL, 16);
1166 machine = audit_elf_to_machine(ival);
1173 /* Here's where we fixup the machine. For example, they give
1174 * x86_64 & want 32 bits we translate that to i686. */
1175 if (bits == ~__AUDIT_ARCH_64BIT && machine == MACH_86_64)
1177 else if (bits == ~__AUDIT_ARCH_64BIT && machine == MACH_PPC64)
1179 else if (bits == ~__AUDIT_ARCH_64BIT && machine == MACH_S390X)
1180 machine = MACH_S390;
1181 else if (bits == ~__AUDIT_ARCH_64BIT && machine == MACH_AARCH64)
1184 /* Check for errors - return -6
1185 * We don't allow 32 bit machines to specify 64 bit. */
1189 if (bits == __AUDIT_ARCH_64BIT)
1193 if (bits == ~__AUDIT_ARCH_64BIT)
1197 if (bits == __AUDIT_ARCH_64BIT)
1201 if (bits == __AUDIT_ARCH_64BIT)
1206 if (bits == __AUDIT_ARCH_64BIT)
1212 if (bits && bits != __AUDIT_ARCH_64BIT)
1216 case MACH_86_64: /* fallthrough */
1217 case MACH_PPC64: /* fallthrough */
1218 case MACH_PPC64LE: /* fallthrough */
1219 case MACH_S390X: /* fallthrough */
1227 int audit_rule_fieldpair_data(struct audit_rule_data **rulep, const char *pair,
1230 const char *f = pair;
1236 struct audit_rule_data *rule = *rulep;
1241 if (rule->field_count >= (AUDIT_MAX_FIELDS - 1))
1244 /* look for 2-char operators first
1245 then look for 1-char operators afterwards
1246 when found, null out the bytes under the operators to split
1247 and set value pointer just past operator bytes
1249 if ( (v = strstr(pair, "!=")) ) {
1252 op = AUDIT_NOT_EQUAL;
1253 } else if ( (v = strstr(pair, ">=")) ) {
1256 op = AUDIT_GREATER_THAN_OR_EQUAL;
1257 } else if ( (v = strstr(pair, "<=")) ) {
1260 op = AUDIT_LESS_THAN_OR_EQUAL;
1261 } else if ( (v = strstr(pair, "&=")) ) {
1264 op = AUDIT_BIT_TEST;
1265 } else if ( (v = strstr(pair, "=")) ) {
1268 } else if ( (v = strstr(pair, ">")) ) {
1270 op = AUDIT_GREATER_THAN;
1271 } else if ( (v = strstr(pair, "<")) ) {
1273 op = AUDIT_LESS_THAN;
1274 } else if ( (v = strstr(pair, "&")) ) {
1276 op = AUDIT_BIT_MASK;
1288 if ((field = audit_name_to_field(f)) < 0)
1291 /* Exclude filter can be used only with MSGTYPE field */
1292 if (flags == AUDIT_FILTER_EXCLUDE && field != AUDIT_MSGTYPE)
1295 rule->fields[rule->field_count] = field;
1296 rule->fieldflags[rule->field_count] = op;
1303 case AUDIT_LOGINUID:
1305 // Do positive & negative separate for 32 bit systems
1307 if (isdigit((char)*(v)))
1308 rule->values[rule->field_count] =
1309 strtoul(v, NULL, 0);
1310 else if (vlen >= 2 && *(v)=='-' &&
1311 (isdigit((char)*(v+1))))
1312 rule->values[rule->field_count] =
1315 if (strcmp(v, "unset") == 0)
1316 rule->values[rule->field_count] =
1318 else if (audit_name_to_uid(v,
1319 &rule->values[rule->field_count])) {
1320 audit_msg(LOG_ERR, "Unknown user: %s",
1331 if (isdigit((char)*(v)))
1332 rule->values[rule->field_count] =
1335 if (audit_name_to_gid(v,
1336 &rule->values[rule->field_count])) {
1337 audit_msg(LOG_ERR, "Unknown group: %s",
1344 if (flags != AUDIT_FILTER_EXIT)
1347 if (isdigit((char)*(v)))
1348 rule->values[rule->field_count] =
1350 else if (vlen >= 2 && *(v)=='-' &&
1351 (isdigit((char)*(v+1))))
1352 rule->values[rule->field_count] =
1355 rule->values[rule->field_count] =
1356 audit_name_to_errno(v);
1357 if (rule->values[rule->field_count] == 0)
1362 if (flags != AUDIT_FILTER_EXCLUDE &&
1363 flags != AUDIT_FILTER_USER)
1366 if (isdigit((char)*(v)))
1367 rule->values[rule->field_count] =
1370 if (audit_name_to_msg_type(v) > 0)
1371 rule->values[rule->field_count] =
1372 audit_name_to_msg_type(v);
1376 /* These next few are strings */
1377 case AUDIT_OBJ_USER:
1378 case AUDIT_OBJ_ROLE:
1379 case AUDIT_OBJ_TYPE:
1380 case AUDIT_OBJ_LEV_LOW:
1381 case AUDIT_OBJ_LEV_HIGH:
1384 /* Watch & object filtering is invalid on anything
1386 if (flags != AUDIT_FILTER_EXIT)
1388 if (field == AUDIT_WATCH || field == AUDIT_DIR)
1389 _audit_permadded = 1;
1392 case AUDIT_SUBJ_USER:
1393 case AUDIT_SUBJ_ROLE:
1394 case AUDIT_SUBJ_TYPE:
1395 case AUDIT_SUBJ_SEN:
1396 case AUDIT_SUBJ_CLR:
1397 case AUDIT_FILTERKEY:
1398 if (field == AUDIT_FILTERKEY && !(_audit_syscalladded || _audit_permadded))
1401 if (field == AUDIT_FILTERKEY &&
1402 vlen > AUDIT_MAX_KEY_LEN)
1404 else if (vlen > PATH_MAX)
1406 rule->values[rule->field_count] = vlen;
1407 offset = rule->buflen;
1408 rule->buflen += vlen;
1409 *rulep = realloc(rule, sizeof(*rule) + rule->buflen);
1410 if (*rulep == NULL) {
1412 audit_msg(LOG_ERR, "Cannot realloc memory!\n");
1417 strncpy(&rule->buf[offset], v, vlen);
1421 if (_audit_syscalladded)
1423 if (!(op == AUDIT_NOT_EQUAL || op == AUDIT_EQUAL))
1425 if (isdigit((char)*(v))) {
1429 _audit_elf = strtoul(v, NULL, 0);
1433 // Make sure we have a valid mapping
1434 machine = audit_elf_to_machine(_audit_elf);
1440 unsigned int machine, elf;
1441 machine = audit_determine_machine(arch);
1442 /* OK, we have the machine type, now convert
1444 elf = audit_machine_to_elf(machine);
1450 rule->values[rule->field_count] = _audit_elf;
1451 _audit_archadded = 1;
1454 if (flags != AUDIT_FILTER_EXIT)
1456 else if (op != AUDIT_EQUAL)
1459 unsigned int i, len, val = 0;
1465 for (i = 0; i < len; i++) {
1466 switch (tolower(v[i])) {
1468 val |= AUDIT_PERM_READ;
1471 val |= AUDIT_PERM_WRITE;
1474 val |= AUDIT_PERM_EXEC;
1477 val |= AUDIT_PERM_ATTR;
1483 rule->values[rule->field_count] = val;
1486 case AUDIT_FILETYPE:
1487 if (!(flags == AUDIT_FILTER_EXIT || flags == AUDIT_FILTER_ENTRY))
1489 rule->values[rule->field_count] =
1490 audit_name_to_ftype(v);
1491 if ((int)rule->values[rule->field_count] < 0) {
1495 case AUDIT_ARG0...AUDIT_ARG3:
1497 if (isdigit((char)*(v)))
1498 rule->values[rule->field_count] =
1499 strtoul(v, NULL, 0);
1500 else if (vlen >= 2 && *(v)=='-' &&
1501 (isdigit((char)*(v+1))))
1502 rule->values[rule->field_count] =
1507 case AUDIT_DEVMAJOR...AUDIT_INODE:
1509 if (flags != AUDIT_FILTER_EXIT)
1513 if (field == AUDIT_INODE) {
1514 if (!(op == AUDIT_NOT_EQUAL ||
1519 if (field == AUDIT_PPID && !(flags == AUDIT_FILTER_EXIT
1520 || flags == AUDIT_FILTER_ENTRY))
1523 if (!isdigit((char)*(v)))
1526 if (field == AUDIT_INODE)
1527 rule->values[rule->field_count] =
1528 strtoul(v, NULL, 0);
1530 rule->values[rule->field_count] =
1534 rule->field_count++;
1538 void audit_rule_free_data(struct audit_rule_data *rule)
1543 static int audit_name_to_uid(const char *name, uid_t *uid)
1547 pw = getpwnam(name);
1551 memset(pw->pw_passwd, ' ', strlen(pw->pw_passwd));
1556 static int audit_name_to_gid(const char *name, gid_t *gid)
1560 gr = getgrnam(name);
1568 int audit_detect_machine(void)
1571 if (uname(&uts) == 0)
1572 // strcpy(uts.machine, "x86_64");
1573 return audit_name_to_machine(uts.machine);
1576 hidden_def(audit_detect_machine)
1579 void audit_number_to_errmsg(int errnumber, const char *opt)
1583 for (i = 0; i < sizeof(err_msgtab)/sizeof(struct msg_tab); i++) {
1584 if (err_msgtab[i].key == errnumber) {
1585 switch (err_msgtab[i].position)
1588 fprintf(stderr, "%s\n",
1589 err_msgtab[i].cvalue);
1592 fprintf(stderr, "%s %s\n", opt,
1593 err_msgtab[i].cvalue);
1596 fprintf(stderr, "%s %s\n",
1597 err_msgtab[i].cvalue, opt);