Imported Upstream version 2.4.3
[platform/upstream/audit.git] / lib / libaudit.c
1 /* libaudit.c -- 
2  * Copyright 2004-2009,2012,2014 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  *      Rickard E. (Rik) Faith <faith@redhat.com>
22  */
23
24 #include "config.h"
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <ctype.h>
31 #include <time.h>
32 #include <pwd.h>
33 #include <grp.h>
34 #include <errno.h>
35 #include <sys/poll.h>
36 #include <sys/utsname.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>      /* O_NOFOLLOW needs gnu defined */
39 #include <limits.h>     /* for PATH_MAX */
40 #include <sys/stat.h>
41 #include <sys/types.h>
42
43 #include "libaudit.h"
44 #include "private.h"
45 #include "errormsg.h"
46
47 /* #defines for the audit failure query  */
48 #define CONFIG_FILE "/etc/libaudit.conf"
49
50 /* Local prototypes */
51 struct nv_pair
52 {
53         const char *name;
54         const char *value;
55 };
56
57 struct kw_pair
58 {
59         const char *name;
60         int (*parser)(const char *, int);
61 };
62
63 struct nv_list
64 {
65         const char *name;
66         int option;
67 };
68
69 struct libaudit_conf
70 {
71         auditfail_t failure_action;
72 };
73
74 static const struct nv_list failure_actions[] =
75 {
76   {"ignore",            FAIL_IGNORE },
77   {"log",               FAIL_LOG },
78   {"terminate",         FAIL_TERMINATE },
79   { NULL,               0 }
80 };
81
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;
87
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);
91
92 static const struct kw_pair keywords[] =
93 {
94   {"failure_action",    audit_failure_parser },
95   { NULL,               NULL }
96 };
97
98 static int audit_priority(int xerrno)
99 {
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)
104                 return LOG_DEBUG;
105         else
106                 return LOG_WARNING;
107 }
108
109 int audit_request_status(int fd)
110 {
111         int rc = audit_send(fd, AUDIT_GET, NULL, 0);
112         if (rc < 0) 
113                 audit_msg(audit_priority(errno),
114                         "Error sending status request (%s)", strerror(-rc));
115         return rc;
116 }
117 hidden_def(audit_request_status)
118
119 /*
120  * Set everything to its default value
121  */
122 static void clear_config(void)
123 {
124         config.failure_action = FAIL_IGNORE;
125 }
126
127 /* Get 1 line from file */
128 static char *get_line(FILE *f, char *buf, size_t len)
129 {
130         if (fgets(buf, len, f)) {
131                 /* remove newline */
132                 char *ptr = strchr(buf, 0x0a);
133                 if (ptr)
134                         *ptr = 0;
135                 return buf;
136         }
137         return NULL;
138 }
139
140 static int nv_split(char *buf, struct nv_pair *nv)
141 {
142         /* Get the name part */
143         char *ptr, *saved=NULL;
144
145         nv->name = NULL;
146         nv->value = NULL;
147         ptr = audit_strsplit_r(buf, &saved);
148         if (ptr == NULL)
149                 return 0; /* If there's nothing, go to next line */
150         if (ptr[0] == '#')
151                 return 0; /* If there's a comment, go to next line */
152         nv->name = ptr;
153
154         /* Check for a '=' */
155         ptr = audit_strsplit_r(NULL, &saved);
156         if (ptr == NULL)
157                 return 1;
158         if (strcmp(ptr, "=") != 0)
159                 return 2;
160
161         /* get the value */
162         ptr = audit_strsplit_r(NULL, &saved);
163         if (ptr == NULL)
164                 return 1;
165         nv->value = ptr;
166
167         /* Make sure there's nothing else */
168         ptr = audit_strsplit_r(NULL, &saved);
169         if (ptr)
170                 return 1;
171
172         /* Everything is OK */
173         return 0;
174 }
175
176 static const struct kw_pair *kw_lookup(const char *val)
177 {
178         int i = 0;
179         while (keywords[i].name != NULL) {
180                 if (strcasecmp(keywords[i].name, val) == 0)
181                         break;
182                 i++;
183         }
184         return &keywords[i];
185 }
186
187 static int audit_failure_parser(const char *val, int line)
188 {
189         int i;
190
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;
195                         return 0;
196                 }
197         }
198         audit_msg(LOG_ERR, "Option %s not found - line %d", val, line);
199         return 1;
200 }
201
202 /*
203  *  Read the /etc/libaudit.conf file and all tunables.
204  */
205 static int load_libaudit_config(const char *path)
206 {
207         int fd, rc, lineno = 1;
208         struct stat st;
209         FILE *f;
210         char buf[128];
211
212         /* open the file */
213         rc = open(path, O_NOFOLLOW|O_RDONLY);
214         if (rc < 0) {
215                 if (errno != ENOENT) {
216                         audit_msg(LOG_ERR, "Error opening %s (%s)",
217                                 path, strerror(errno));
218                         return 1;
219                 }
220                 audit_msg(LOG_WARNING,
221                         "Config file %s doesn't exist, skipping", path);
222                 return 0;
223         }
224         fd = rc;
225
226         /* check the file's permissions: owned by root, not world writable,
227          * not symlink.
228          */
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));
233                 close(fd);
234                 return 1;
235         }
236         if (st.st_uid != 0) {
237                 audit_msg(LOG_ERR, "Error - %s isn't owned by root", path);
238                 close(fd);
239                 return 1;
240         }
241         if ((st.st_mode & S_IWOTH) == S_IWOTH) {
242                 audit_msg(LOG_ERR, "Error - %s is world writable", path);
243                 close(fd);
244                 return 1;
245         }
246         if (!S_ISREG(st.st_mode)) {
247                 audit_msg(LOG_ERR, "Error - %s is not a regular file", path);
248                 close(fd);
249                 return 1;
250         }
251
252         /* it's ok, read line by line */
253         f = fdopen(fd, "rm");
254         if (f == NULL) {
255                 audit_msg(LOG_ERR, "Error - fdopen failed (%s)",
256                         strerror(errno));
257                 close(fd);
258                 return 1;
259         }
260
261         while (get_line(f, buf, sizeof(buf))) {
262                 // convert line into name-value pair
263                 const struct kw_pair *kw;
264                 struct nv_pair nv;
265                 rc = nv_split(buf, &nv);
266                 switch (rc) {
267                         case 0: // fine
268                                 break;
269                         case 1: // not the right number of tokens.
270                                 audit_msg(LOG_ERR,
271                                 "Wrong number of arguments for line %d in %s",
272                                         lineno, path);
273                                 break;
274                         case 2: // no '=' sign
275                                 audit_msg(LOG_ERR,
276                                         "Missing equal sign for line %d in %s",
277                                         lineno, path);
278                                 break;
279                         default: // something else went wrong...
280                                 audit_msg(LOG_ERR,
281                                         "Unknown error for line %d in %s",
282                                         lineno, path);
283                                 break;
284                 }
285                 if (nv.name == NULL) {
286                         lineno++;
287                         continue;
288                 }
289                 if (nv.value == NULL) {
290                         fclose(f);
291                         return 1;
292                 }
293
294                 /* identify keyword or error */
295                 kw = kw_lookup(nv.name);
296                 if (kw->name == NULL) {
297                         audit_msg(LOG_ERR,
298                                 "Unknown keyword \"%s\" in line %d of %s",
299                                 nv.name, lineno, path);
300                         fclose(f);
301                         return 1;
302                 }
303
304                 /* dispatch to keyword's local parser */
305                 rc = kw->parser(nv.value, lineno);
306                 if (rc != 0) {
307                         fclose(f);
308                         return 1; // local parser puts message out
309                 }
310
311                 lineno++;
312         }
313
314         fclose(f);
315         return 0;
316 }
317
318
319 /*
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.
324  */
325 int get_auditfail_action(auditfail_t *failmode)
326 {
327         clear_config();
328
329         if (load_libaudit_config(CONFIG_FILE)) {
330                 *failmode = config.failure_action;
331                 return 1;
332         }
333
334         *failmode = config.failure_action;
335         return 0;
336 }
337
338 int audit_set_enabled(int fd, uint32_t enabled)
339 {
340         int rc;
341         struct audit_status s;
342
343         memset(&s, 0, sizeof(s));
344         s.mask    = AUDIT_STATUS_ENABLED;
345         s.enabled = enabled;
346         rc = audit_send(fd, AUDIT_SET, &s, sizeof(s));
347         if (rc < 0)
348                 audit_msg(audit_priority(errno),
349                         "Error sending enable request (%s)", strerror(-rc));
350         return rc;
351 }
352
353 /* 
354  * This function will return 0 if auditing is NOT enabled and
355  * 1 if enabled, and -1 on error.
356  */
357 int audit_is_enabled(int fd)
358 {
359         int rc;
360
361         if (fd < 0)
362                 return 0;
363
364         if ((rc = audit_request_status(fd)) > 0) {
365                 struct audit_reply rep;
366                 int i;
367                 int timeout = 40; /* tenths of seconds */
368                 struct pollfd pfd[1];
369
370                 pfd[0].fd = fd;
371                 pfd[0].events = POLLIN;
372
373                 for (i = 0; i < timeout; i++) {
374                         do {
375                                 rc = poll(pfd, 1, 100);
376                         } while (rc < 0 && errno == EINTR);
377
378                         rc = audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING,0);
379                         if (rc > 0) {
380                                 /* If we get done or error, break out */
381                                 if (rep.type == NLMSG_DONE || 
382                                         rep.type == NLMSG_ERROR)
383                                         break;
384
385                                 /* If its not status, keep looping */
386                                 if (rep.type != AUDIT_GET)
387                                         continue;
388
389                                 /* Found it... */
390                                 return rep.status->enabled;
391                         }
392                 }
393         }
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". */
398                 return 0;
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. */
406                 return 0;
407         }
408         return -1;
409 }
410
411 int audit_set_failure(int fd, uint32_t failure)
412 {
413         int rc;
414         struct audit_status s;
415
416         memset(&s, 0, sizeof(s));
417         s.mask    = AUDIT_STATUS_FAILURE;
418         s.failure = failure;
419         rc = audit_send(fd, AUDIT_SET, &s, sizeof(s));
420         if (rc < 0)
421                 audit_msg(audit_priority(errno), 
422                         "Error sending failure mode request (%s)", 
423                         strerror(-rc));
424         return rc;
425 }
426
427 /*
428  * This function returns -1 on error and 1 on success.
429  */
430 int audit_set_pid(int fd, uint32_t pid, rep_wait_t wmode)
431 {
432         struct audit_status s;
433         struct audit_reply rep;
434         struct pollfd pfd[1];
435         int rc;
436
437         memset(&s, 0, sizeof(s));
438         s.mask    = AUDIT_STATUS_PID;
439         s.pid     = pid;
440         rc = audit_send(fd, AUDIT_SET, &s, sizeof(s));
441         if (rc < 0) {
442                 audit_msg(audit_priority(errno), 
443                         "Error setting audit daemon pid (%s)", 
444                         strerror(-rc));
445                 return rc;
446         }
447         if (wmode == WAIT_NO)
448                 return 1;
449
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. */
454         pfd[0].fd = fd;
455         pfd[0].events = POLLIN;
456         do {
457                 rc = poll(pfd, 1, 100); /* .1 second */
458         } while (rc < 0 && errno == EINTR);
459
460         (void)audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0);
461         return 1;
462 }
463
464 int audit_set_rate_limit(int fd, uint32_t limit)
465 {
466         int rc;
467         struct audit_status s;
468
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));
473         if (rc < 0)
474                 audit_msg(audit_priority(errno),
475                         "Error sending rate limit request (%s)", 
476                         strerror(-rc));
477         return rc;
478 }
479
480 int audit_set_backlog_limit(int fd, uint32_t limit)
481 {
482         int rc;
483         struct audit_status s;
484
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));
489         if (rc < 0)
490                 audit_msg(audit_priority(errno),
491                         "Error sending backlog limit request (%s)", 
492                         strerror(-rc));
493         return rc;
494 }
495
496 int audit_set_backlog_wait_time(int fd, uint32_t bwt)
497 {
498         int rc = -1;
499 #if HAVE_DECL_AUDIT_VERSION_BACKLOG_WAIT_TIME
500         struct audit_status s;
501
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));
506         if (rc < 0)
507                 audit_msg(audit_priority(errno),
508                         "Error sending backlog limit request (%s)", 
509                         strerror(-rc));
510 #endif
511         return rc;
512 }
513
514 int audit_set_feature(int fd, unsigned feature, unsigned value, unsigned lock)
515 {
516 #if HAVE_DECL_AUDIT_FEATURE_VERSION
517         int rc;
518         struct audit_features f;
519
520         memset(&f, 0, sizeof(f));
521         f.mask = AUDIT_FEATURE_TO_MASK(feature);
522         if (value)
523                 f.features = AUDIT_FEATURE_TO_MASK(feature);
524         if (lock)
525                 f.lock = AUDIT_FEATURE_TO_MASK(feature);
526         rc = audit_send(fd, AUDIT_SET_FEATURE, &f, sizeof(f));
527         if (rc < 0)
528                 audit_msg(audit_priority(errno),
529                         "Error setting feature (%s)", 
530                         strerror(-rc));
531         return rc;
532 #else
533         errno = EINVAL;
534         return -1;
535 #endif
536 }
537 hidden_def(audit_set_feature)
538
539 int audit_request_features(int fd)
540 {
541 #if HAVE_DECL_AUDIT_FEATURE_VERSION
542         int rc;
543         struct audit_features f;
544
545         memset(&f, 0, sizeof(f));
546         rc = audit_send(fd, AUDIT_GET_FEATURE, &f, sizeof(f));
547         if (rc < 0)
548                 audit_msg(audit_priority(errno),
549                         "Error getting feature (%s)", 
550                         strerror(-rc));
551         return rc;
552 #else
553         errno = EINVAL;
554         return -1;
555 #endif
556 }
557 hidden_def(audit_request_features)
558
559 extern int  audit_set_loginuid_immutable(int fd)
560 {
561 #if HAVE_DECL_AUDIT_FEATURE_VERSION
562         return audit_set_feature(fd, AUDIT_FEATURE_LOGINUID_IMMUTABLE, 1, 1);
563 #else
564         errno = EINVAL;
565         return -1;
566 #endif
567 }
568
569 int audit_request_rules_list_data(int fd)
570 {
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)", 
575                         strerror(-rc));
576         return rc;
577 }
578
579 int audit_request_signal_info(int fd)
580 {
581         int rc = audit_send(fd, AUDIT_SIGNAL_INFO, NULL, 0);
582         if (rc < 0)
583                 audit_msg(LOG_WARNING,
584                         "Error sending signal_info request (%s)",
585                         strerror(-rc));
586         return rc;
587 }
588
589 int audit_update_watch_perms(struct audit_rule_data *rule, int perms)
590 {
591         int i, done=0;
592
593         if (rule->field_count < 1)
594                 return -1;
595
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;
600                         done = 1;
601                 }
602         }
603         if (!done) {
604                 // If not check to see if we have room to add a field
605                 if (rule->field_count >= (AUDIT_MAX_FIELDS - 1))
606                         return -2;
607         
608                 // Add the perm
609                 rule->fields[rule->field_count] = AUDIT_PERM;
610                 rule->fieldflags[rule->field_count] = AUDIT_EQUAL;
611                 rule->values[rule->field_count] = perms;
612                 rule->field_count++;
613         }
614         return 0;
615 }
616
617 int audit_add_watch(struct audit_rule_data **rulep, const char *path)
618 {
619         return audit_add_watch_dir(AUDIT_WATCH, rulep, path);
620 }
621
622 int audit_add_dir(struct audit_rule_data **rulep, const char *path)
623 {
624         return audit_add_watch_dir(AUDIT_DIR, rulep, path);
625 }
626
627 int audit_add_watch_dir(int type, struct audit_rule_data **rulep,
628                         const char *path)
629 {
630         size_t len = strlen(path);
631         struct audit_rule_data *rule = *rulep;
632
633         if (rule && rule->field_count) {
634                 audit_msg(LOG_ERR, "Rule is not empty\n");
635                 return -1;
636         }
637         if (type != AUDIT_WATCH && type != AUDIT_DIR) {
638                 audit_msg(LOG_ERR, "Invalid type used\n");
639                 return -1;
640         }
641
642         *rulep = realloc(rule, len + sizeof(*rule));
643         if (*rulep == NULL) {
644                 free(rule);
645                 audit_msg(LOG_ERR, "Cannot realloc memory!\n");
646                 return -1;
647         }
648         rule = *rulep;
649         memset(rule, 0, len + sizeof(*rule));
650
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;
658         rule->buflen = len;
659         memcpy(&rule->buf[0], path, len);
660
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;
666         
667         _audit_permadded = 1;
668
669         return  0;
670 }
671 hidden_def(audit_add_watch_dir)
672
673 int audit_add_rule_data(int fd, struct audit_rule_data *rule,
674                         int flags, int action)
675 {
676         int rc;
677
678         if (flags == AUDIT_FILTER_ENTRY) {
679                 audit_msg(LOG_WARNING, "Use of entry filter is deprecated");
680                 return -2;
681         }
682         rule->flags  = flags;
683         rule->action = action;
684         rc = audit_send(fd, AUDIT_ADD_RULE, rule, 
685                         sizeof(struct audit_rule_data) + rule->buflen);
686         if (rc < 0)
687                 audit_msg(audit_priority(errno),
688                         "Error sending add rule data request (%s)",
689                                 errno == EEXIST ? 
690                                 "Rule exists" : strerror(-rc));
691         return rc;
692 }
693
694 int audit_delete_rule_data(int fd, struct audit_rule_data *rule,
695                            int flags, int action)
696 {
697         int rc;
698
699         if (flags == AUDIT_FILTER_ENTRY) {
700                 audit_msg(LOG_WARNING, "Use of entry filter is deprecated");
701                 return -2;
702         }
703         rule->flags  = flags;
704         rule->action = action;
705         rc = audit_send(fd, AUDIT_DEL_RULE, rule, 
706                         sizeof(struct audit_rule_data) + rule->buflen);
707         if (rc < 0) {
708                 if (rc == -ENOENT)
709                         audit_msg(LOG_WARNING,
710                         "Error sending delete rule request (No rule matches)");
711                 else
712                         audit_msg(audit_priority(errno),
713                                 "Error sending delete rule data request (%s)",
714                                 strerror(-rc));
715         }
716         return rc;
717 }
718
719 /*
720  * This function is part of the directory auditing code
721  */
722 int audit_trim_subtrees(int fd)
723 {
724         int rc = audit_send(fd, AUDIT_TRIM, NULL, 0);
725         if (rc < 0) 
726                 audit_msg(audit_priority(errno),
727                         "Error sending trim subtrees command (%s)",
728                         strerror(-rc));
729         return rc;
730 }
731
732 /*
733  * This function is part of the directory auditing code
734  */
735 int audit_make_equivalent(int fd, const char *mount_point,
736                          const char *subtree)
737 {
738         int rc;
739         size_t len1 = strlen(mount_point);
740         size_t len2 = strlen(subtree);
741         struct {
742                 uint32_t sizes[2];
743                 unsigned char buf[];
744         } *cmd = malloc(sizeof(*cmd) + len1 + len2);
745
746         memset(cmd, 0, sizeof(*cmd) + len1 + len2);
747
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);
752
753         rc = audit_send(fd, AUDIT_MAKE_EQUIV, cmd, sizeof(*cmd) + len1 + len2);
754         if (rc < 0) 
755                 audit_msg(audit_priority(errno),
756                         "Error sending make_equivalent command (%s)",
757                         strerror(-rc));
758         free(cmd);
759         return rc;
760 }
761
762 /*
763  * This function will retreive the loginuid or -1 if there
764  * is an error.
765  */
766 uid_t audit_getloginuid(void)
767 {
768         uid_t uid;
769         int len, in;
770         char buf[16];
771
772         errno = 0;
773         in = open("/proc/self/loginuid", O_NOFOLLOW|O_RDONLY);
774         if (in < 0)
775                 return -1;
776         do {
777                 len = read(in, buf, sizeof(buf));
778         } while (len < 0 && errno == EINTR);
779         close(in);
780         if (len < 0 || len >= sizeof(buf))
781                 return -1;
782         buf[len] = 0;
783         errno = 0;
784         uid = strtol(buf, 0, 10);
785         if (errno)
786                 return -1;
787         else
788                 return uid;
789 }
790
791 /*
792  * This function returns 0 on success and 1 on failure
793  */
794 int audit_setloginuid(uid_t uid)
795 {
796         char loginuid[16];
797         int o, count, rc = 0;
798
799         errno = 0;
800         count = snprintf(loginuid, sizeof(loginuid), "%u", uid);
801         o = open("/proc/self/loginuid", O_NOFOLLOW|O_WRONLY|O_TRUNC);
802         if (o >= 0) {
803                 int block, offset = 0;
804
805                 while (count > 0) {
806                         block = write(o, &loginuid[offset], (unsigned)count);
807
808                         if (block < 0) {
809                                 if (errno == EINTR)
810                                         continue;
811                                 audit_msg(LOG_ERR, "Error writing loginuid");
812                                 close(o);
813                                 return 1;
814                         }
815                         offset += block;
816                         count -= block;
817                 }
818                 close(o);
819         } else {
820                 audit_msg(LOG_ERR, "Error opening /proc/self/loginuid");
821                 rc = 1;
822         }
823         return rc;
824 }
825
826 int audit_rule_syscall_data(struct audit_rule_data *rule, int scall)
827 {
828         int word = AUDIT_WORD(scall);
829         int bit  = AUDIT_BIT(scall);
830
831         if (word >= (AUDIT_BITMASK_SIZE-1)) 
832                 return -1;
833         rule->mask[word] |= bit;
834         return 0;
835 }
836 hidden_def(audit_rule_syscall_data)
837
838 int audit_rule_syscallbyname_data(struct audit_rule_data *rule,
839                                   const char *scall)
840 {
841         int nr, i;
842         int machine;
843
844         if (!strcmp(scall, "all")) {
845                 for (i = 0; i < (AUDIT_BITMASK_SIZE-1); i++) 
846                         rule->mask[i] = ~0;
847                 return 0;
848         }
849         if (!_audit_elf)
850                 machine = audit_detect_machine();
851         else
852                 machine = audit_elf_to_machine(_audit_elf);
853         if (machine < 0)
854                 return -2;
855         nr = audit_name_to_syscall(scall, machine);
856         if (nr < 0) {
857                 if (isdigit(scall[0]))
858                         nr = strtol(scall, NULL, 0);
859         }
860         if (nr >= 0) 
861                 return audit_rule_syscall_data(rule, nr);
862         return -1;
863 }
864 hidden_def(audit_rule_syscallbyname_data)
865
866 int audit_rule_interfield_comp_data(struct audit_rule_data **rulep,
867                                          const char *pair,
868                                          int flags) {
869         const char *f = pair;
870         char       *v;
871         int        op;
872         int        field1, field2;
873         struct audit_rule_data *rule = *rulep;
874
875         if (f == NULL)
876                 return -1;
877
878         if (rule->field_count >= (AUDIT_MAX_FIELDS - 1))
879                 return -28;
880
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
885         */
886         if ( (v = strstr(pair, "!=")) ) {
887                 *v++ = '\0';
888                 *v++ = '\0';
889                 op = AUDIT_NOT_EQUAL;
890         } else if ( (v = strstr(pair, "=")) ) {
891                 *v++ = '\0';
892                 op = AUDIT_EQUAL;
893         } else {
894                 return -13;
895         }
896
897         if (*f == 0)
898                 return -24;
899
900         if (*v == 0)
901                 return -25;
902
903         if ((field1 = audit_name_to_field(f)) < 0)
904                 return -26;
905
906         if ((field2 = audit_name_to_field(v)) < 0)
907                 return -27;
908
909         /* Interfield comparison can only be in exit filter */
910         if (flags != AUDIT_FILTER_EXIT)
911                 return -7;
912
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 */
917         switch (field1)
918         {
919                 /* UID comparison */
920                 case AUDIT_EUID:
921                         switch(field2) {
922                         case AUDIT_LOGINUID:
923                                 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_EUID;
924                                 break;
925                         case AUDIT_FSUID:
926                                 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_FSUID;
927                                 break;
928                         case AUDIT_OBJ_UID:
929                                 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_OBJ_UID;
930                                 break;
931                         case AUDIT_SUID:
932                                 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_SUID;
933                                 break;
934                         case AUDIT_UID:
935                                 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_EUID;
936                                 break;
937                         default:
938                                 return -1;
939                         }
940                         break;
941                 case AUDIT_FSUID:
942                         switch(field2) {
943                         case AUDIT_LOGINUID:
944                                 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_FSUID;
945                                 break;
946                         case AUDIT_EUID:
947                                 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_FSUID;
948                                 break;
949                         case AUDIT_OBJ_UID:
950                                 rule->values[rule->field_count] = AUDIT_COMPARE_FSUID_TO_OBJ_UID;
951                                 break;
952                         case AUDIT_SUID:
953                                 rule->values[rule->field_count] = AUDIT_COMPARE_SUID_TO_FSUID;
954                                 break;
955                         case AUDIT_UID:
956                                 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_FSUID;
957                                 break;
958                         default:
959                                 return -1;
960                         }
961                         break;
962                 case AUDIT_LOGINUID:
963                         switch(field2) {
964                         case AUDIT_EUID:
965                                 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_EUID;
966                                 break;
967                         case AUDIT_FSUID:
968                                 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_FSUID;
969                                 break;
970                         case AUDIT_OBJ_UID:
971                                 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_OBJ_UID;
972                                 break;
973                         case AUDIT_SUID:
974                                 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_SUID;
975                                 break;
976                         case AUDIT_UID:
977                                 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_AUID;
978                                 break;
979                         default:
980                                 return -1;
981                         }
982                         break;
983                 case AUDIT_SUID:
984                         switch(field2) {
985                         case AUDIT_LOGINUID:
986                                 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_SUID;
987                                 break;
988                         case AUDIT_EUID:
989                                 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_SUID;
990                                 break;
991                         case AUDIT_FSUID:
992                                 rule->values[rule->field_count] = AUDIT_COMPARE_SUID_TO_FSUID;
993                                 break;
994                         case AUDIT_OBJ_UID:
995                                 rule->values[rule->field_count] = AUDIT_COMPARE_SUID_TO_OBJ_UID;
996                                 break;
997                         case AUDIT_UID:
998                                 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_SUID;
999                                 break;
1000                         default:
1001                                 return -1;
1002                         }
1003                         break;
1004                 case AUDIT_OBJ_UID:
1005                         switch(field2) {
1006                         case AUDIT_LOGINUID:
1007                                 rule->values[rule->field_count] = AUDIT_COMPARE_AUID_TO_OBJ_UID;
1008                                 break;
1009                         case AUDIT_EUID:
1010                                 rule->values[rule->field_count] = AUDIT_COMPARE_EUID_TO_OBJ_UID;
1011                                 break;
1012                         case AUDIT_FSUID:
1013                                 rule->values[rule->field_count] = AUDIT_COMPARE_FSUID_TO_OBJ_UID;
1014                                 break;
1015                         case AUDIT_UID:
1016                                 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_OBJ_UID;
1017                                 break;
1018                         case AUDIT_SUID:
1019                                 rule->values[rule->field_count] = AUDIT_COMPARE_SUID_TO_OBJ_UID;
1020                                 break;
1021                         default:
1022                                 return -1;
1023                         }
1024                         break;
1025                 case AUDIT_UID:
1026                         switch(field2) {
1027                         case AUDIT_LOGINUID:
1028                                 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_AUID;
1029                                 break;
1030                         case AUDIT_EUID:
1031                                 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_EUID;
1032                                 break;
1033                         case AUDIT_FSUID:
1034                                 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_FSUID;
1035                                 break;
1036                         case AUDIT_OBJ_UID:
1037                                 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_OBJ_UID;
1038                                 break;
1039                         case AUDIT_SUID:
1040                                 rule->values[rule->field_count] = AUDIT_COMPARE_UID_TO_SUID;
1041                                 break;
1042                         default:
1043                                 return -1;
1044                         }
1045                         break;
1046
1047                 /* GID comparisons */
1048                 case AUDIT_EGID:
1049                         switch(field2) {
1050                         case AUDIT_FSGID:
1051                                 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_FSGID;
1052                                 break;
1053                         case AUDIT_GID:
1054                                 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_EGID;
1055                                 break;
1056                         case AUDIT_OBJ_GID:
1057                                 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_OBJ_GID;
1058                                 break;
1059                         case AUDIT_SGID:
1060                                 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_SGID;
1061                                 break;
1062                         default:
1063                                 return -1;
1064                         }
1065                         break;
1066                 case AUDIT_FSGID:
1067                         switch(field2) {
1068                         case AUDIT_SGID:
1069                                 rule->values[rule->field_count] = AUDIT_COMPARE_SGID_TO_FSGID;
1070                                 break;
1071                         case AUDIT_GID:
1072                                 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_FSGID;
1073                                 break;
1074                         case AUDIT_OBJ_GID:
1075                                 rule->values[rule->field_count] = AUDIT_COMPARE_FSGID_TO_OBJ_GID;
1076                                 break;
1077                         case AUDIT_EGID:
1078                                 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_FSGID;
1079                                 break;
1080                         default:
1081                                 return -1;
1082                         }
1083                         break;
1084                 case AUDIT_GID:
1085                         switch(field2) {
1086                         case AUDIT_EGID:
1087                                 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_EGID;
1088                                 break;
1089                         case AUDIT_FSGID:
1090                                 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_FSGID;
1091                                 break;
1092                         case AUDIT_OBJ_GID:
1093                                 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_OBJ_GID;
1094                                 break;
1095                         case AUDIT_SGID:
1096                                 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_SGID;
1097                                 break;
1098                         default:
1099                                 return -1;
1100                         }
1101                         break;
1102                 case AUDIT_OBJ_GID:
1103                         switch(field2) {
1104                         case AUDIT_EGID:
1105                                 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_OBJ_GID;
1106                                 break;
1107                         case AUDIT_FSGID:
1108                                 rule->values[rule->field_count] = AUDIT_COMPARE_FSGID_TO_OBJ_GID;
1109                                 break;
1110                         case AUDIT_GID:
1111                                 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_OBJ_GID;
1112                                 break;
1113                         case AUDIT_SGID:
1114                                 rule->values[rule->field_count] = AUDIT_COMPARE_SGID_TO_OBJ_GID;
1115                                 break;
1116                         default:
1117                                 return -1;
1118                         }
1119                         break;
1120                 case AUDIT_SGID:
1121                         switch(field2) {
1122                         case AUDIT_FSGID:
1123                                 rule->values[rule->field_count] = AUDIT_COMPARE_SGID_TO_FSGID;
1124                                 break;
1125                         case AUDIT_GID:
1126                                 rule->values[rule->field_count] = AUDIT_COMPARE_GID_TO_SGID;
1127                                 break;
1128                         case AUDIT_OBJ_GID:
1129                                 rule->values[rule->field_count] = AUDIT_COMPARE_SGID_TO_OBJ_GID;
1130                                 break;
1131                         case AUDIT_EGID:
1132                                 rule->values[rule->field_count] = AUDIT_COMPARE_EGID_TO_SGID;
1133                                 break;
1134                         default:
1135                                 return -1;
1136                         }
1137                         break;
1138                 default:
1139                         return -1;
1140                         break;
1141         }
1142         rule->field_count++;
1143         return 0;
1144 }
1145
1146 int audit_determine_machine(const char *arch)
1147 {       // What do we want? i686, x86_64, ia64 or b64, b32
1148         int machine;
1149         unsigned int bits = 0;
1150
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();
1157         } else { 
1158                 machine = audit_name_to_machine(arch);
1159                 if (machine < 0) {
1160                         // See if its numeric
1161                         unsigned int ival;
1162                         errno = 0;
1163                         ival = strtoul(arch, NULL, 16);
1164                         if (errno)
1165                                 return -4;
1166                         machine = audit_elf_to_machine(ival);
1167                 }
1168         }
1169
1170         if (machine < 0) 
1171                 return -4;
1172
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)
1176                 machine = MACH_X86;
1177         else if (bits == ~__AUDIT_ARCH_64BIT && machine == MACH_PPC64)
1178                 machine = MACH_PPC;
1179         else if (bits == ~__AUDIT_ARCH_64BIT && machine == MACH_S390X)
1180                 machine = MACH_S390;
1181         else if (bits == ~__AUDIT_ARCH_64BIT && machine == MACH_AARCH64)
1182                 machine = MACH_ARM;
1183
1184         /* Check for errors - return -6 
1185          * We don't allow 32 bit machines to specify 64 bit. */
1186         switch (machine)
1187         {
1188                 case MACH_X86:
1189                         if (bits == __AUDIT_ARCH_64BIT)
1190                                 return -6;
1191                         break;
1192                 case MACH_IA64:
1193                         if (bits == ~__AUDIT_ARCH_64BIT)
1194                                 return -6;
1195                         break;
1196                 case MACH_PPC:
1197                         if (bits == __AUDIT_ARCH_64BIT)
1198                                 return -6;
1199                         break;
1200                 case MACH_S390:
1201                         if (bits == __AUDIT_ARCH_64BIT)
1202                                 return -6;
1203                         break;
1204 #ifdef WITH_ARM
1205                 case MACH_ARM:
1206                         if (bits == __AUDIT_ARCH_64BIT)
1207                                 return -6;
1208                         break;
1209 #endif
1210 #ifdef WITH_AARCH64
1211                 case MACH_AARCH64:
1212                         if (bits && bits != __AUDIT_ARCH_64BIT)
1213                                 return -6;
1214                         break;
1215 #endif
1216                 case MACH_86_64:   /* fallthrough */
1217                 case MACH_PPC64:   /* fallthrough */
1218                 case MACH_PPC64LE: /* fallthrough */
1219                 case MACH_S390X:   /* fallthrough */
1220                         break;
1221                 default:
1222                         return -6;
1223         }
1224         return machine;
1225 }
1226
1227 int audit_rule_fieldpair_data(struct audit_rule_data **rulep, const char *pair,
1228                               int flags)
1229 {
1230         const char *f = pair;
1231         char       *v;
1232         int        op;
1233         int        field;
1234         int        vlen;
1235         int        offset;
1236         struct audit_rule_data *rule = *rulep;
1237
1238         if (f == NULL)
1239                 return -1;
1240
1241         if (rule->field_count >= (AUDIT_MAX_FIELDS - 1))
1242                 return -28;
1243
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
1248         */
1249         if ( (v = strstr(pair, "!=")) ) {
1250                 *v++ = '\0';
1251                 *v++ = '\0';
1252                 op = AUDIT_NOT_EQUAL;
1253         } else if ( (v = strstr(pair, ">=")) ) {
1254                 *v++ = '\0';
1255                 *v++ = '\0';
1256                 op = AUDIT_GREATER_THAN_OR_EQUAL;
1257         } else if ( (v = strstr(pair, "<=")) ) {
1258                 *v++ = '\0';
1259                 *v++ = '\0';
1260                 op = AUDIT_LESS_THAN_OR_EQUAL;
1261         } else if ( (v = strstr(pair, "&=")) ) {
1262                 *v++ = '\0';
1263                 *v++ = '\0';
1264                 op = AUDIT_BIT_TEST;
1265         } else if ( (v = strstr(pair, "=")) ) {
1266                 *v++ = '\0';
1267                 op = AUDIT_EQUAL;
1268         } else if ( (v = strstr(pair, ">")) ) {
1269                 *v++ = '\0';
1270                 op = AUDIT_GREATER_THAN;
1271         } else if ( (v = strstr(pair, "<")) ) {
1272                 *v++ = '\0';
1273                 op = AUDIT_LESS_THAN;
1274         } else if ( (v = strstr(pair, "&")) ) {
1275                 *v++ = '\0';
1276                 op = AUDIT_BIT_MASK;
1277         }
1278
1279         if (v == NULL)
1280                 return -1;
1281         
1282         if (*f == 0)
1283                 return -22;
1284
1285         if (*v == 0)
1286                 return -20;
1287
1288         if ((field = audit_name_to_field(f)) < 0) 
1289                 return -2;
1290
1291         /* Exclude filter can be used only with MSGTYPE field */
1292         if (flags == AUDIT_FILTER_EXCLUDE && field != AUDIT_MSGTYPE)
1293                 return -12; 
1294
1295         rule->fields[rule->field_count] = field;
1296         rule->fieldflags[rule->field_count] = op;
1297         switch (field)
1298         {
1299                 case AUDIT_UID:
1300                 case AUDIT_EUID:
1301                 case AUDIT_SUID:
1302                 case AUDIT_FSUID:
1303                 case AUDIT_LOGINUID:
1304                 case AUDIT_OBJ_UID:
1305                         // Do positive & negative separate for 32 bit systems
1306                         vlen = strlen(v);
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] =
1313                                         strtol(v, NULL, 0);
1314                         else {
1315                                 if (strcmp(v, "unset") == 0)
1316                                         rule->values[rule->field_count] =
1317                                                                 4294967295;
1318                                 else if (audit_name_to_uid(v, 
1319                                         &rule->values[rule->field_count])) {
1320                                         audit_msg(LOG_ERR, "Unknown user: %s",
1321                                                 v);
1322                                         return -2;
1323                                 }
1324                         }
1325                         break;
1326                 case AUDIT_GID:
1327                 case AUDIT_EGID:
1328                 case AUDIT_SGID:
1329                 case AUDIT_FSGID:
1330                 case AUDIT_OBJ_GID:
1331                         if (isdigit((char)*(v))) 
1332                                 rule->values[rule->field_count] = 
1333                                         strtol(v, NULL, 0);
1334                         else {
1335                                 if (audit_name_to_gid(v, 
1336                                         &rule->values[rule->field_count])) {
1337                                         audit_msg(LOG_ERR, "Unknown group: %s",
1338                                                 v);
1339                                         return -2;
1340                                 }
1341                         }
1342                         break;
1343                 case AUDIT_EXIT:
1344                         if (flags != AUDIT_FILTER_EXIT)
1345                                 return -7;
1346                         vlen = strlen(v);
1347                         if (isdigit((char)*(v))) 
1348                                 rule->values[rule->field_count] = 
1349                                         strtol(v, NULL, 0);
1350                         else if (vlen >= 2 && *(v)=='-' && 
1351                                                 (isdigit((char)*(v+1)))) 
1352                                 rule->values[rule->field_count] = 
1353                                         strtol(v, NULL, 0);
1354                         else {
1355                                 rule->values[rule->field_count] = 
1356                                                 audit_name_to_errno(v);
1357                                 if (rule->values[rule->field_count] == 0) 
1358                                         return -15;
1359                         }
1360                         break;
1361                 case AUDIT_MSGTYPE:
1362                         if (flags != AUDIT_FILTER_EXCLUDE &&
1363                                         flags != AUDIT_FILTER_USER)
1364                                 return -9;
1365
1366                         if (isdigit((char)*(v)))
1367                                 rule->values[rule->field_count] =
1368                                         strtol(v, NULL, 0);
1369                         else
1370                                 if (audit_name_to_msg_type(v) > 0)
1371                                         rule->values[rule->field_count] =
1372                                                 audit_name_to_msg_type(v);
1373                                 else
1374                                         return -8;
1375                         break;
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:
1382                 case AUDIT_WATCH:
1383                 case AUDIT_DIR:
1384                         /* Watch & object filtering is invalid on anything
1385                          * but exit */
1386                         if (flags != AUDIT_FILTER_EXIT)
1387                                 return -7;
1388                         if (field == AUDIT_WATCH || field == AUDIT_DIR)
1389                                 _audit_permadded = 1;
1390
1391                         /* fallthrough */
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))
1399                                 return -19;
1400                         vlen = strlen(v);
1401                         if (field == AUDIT_FILTERKEY &&
1402                                         vlen > AUDIT_MAX_KEY_LEN)
1403                                 return -11;
1404                         else if (vlen > PATH_MAX)
1405                                 return -11;
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) {
1411                                 free(rule);
1412                                 audit_msg(LOG_ERR, "Cannot realloc memory!\n");
1413                                 return -3;
1414                         } else {
1415                                 rule = *rulep;
1416                         }
1417                         strncpy(&rule->buf[offset], v, vlen);
1418
1419                         break;
1420                 case AUDIT_ARCH:
1421                         if (_audit_syscalladded) 
1422                                 return -3;
1423                         if (!(op == AUDIT_NOT_EQUAL || op == AUDIT_EQUAL))
1424                                 return -13;
1425                         if (isdigit((char)*(v))) {
1426                                 int machine;
1427
1428                                 errno = 0;
1429                                 _audit_elf = strtoul(v, NULL, 0);
1430                                 if (errno) 
1431                                         return -5;
1432
1433                                 // Make sure we have a valid mapping
1434                                 machine = audit_elf_to_machine(_audit_elf);
1435                                 if (machine < 0)
1436                                         return -5;
1437                         }
1438                         else {
1439                                 const char *arch=v;
1440                                 unsigned int machine, elf;
1441                                 machine = audit_determine_machine(arch);
1442                                 /* OK, we have the machine type, now convert
1443                                    to elf. */
1444                                 elf = audit_machine_to_elf(machine);
1445                                 if (elf == 0)
1446                                         return -5;
1447
1448                                 _audit_elf = elf;
1449                         }
1450                         rule->values[rule->field_count] = _audit_elf; 
1451                         _audit_archadded = 1;
1452                         break;
1453                 case AUDIT_PERM:
1454                         if (flags != AUDIT_FILTER_EXIT)
1455                                 return -7;
1456                         else if (op != AUDIT_EQUAL)
1457                                 return -13;
1458                         else {
1459                                 unsigned int i, len, val = 0;
1460
1461                                 len = strlen(v);
1462                                 if (len > 4)
1463                                         return -11;
1464
1465                                 for (i = 0; i < len; i++) {
1466                                         switch (tolower(v[i])) {
1467                                                 case 'r':
1468                                                         val |= AUDIT_PERM_READ;
1469                                                         break;
1470                                                 case 'w':
1471                                                         val |= AUDIT_PERM_WRITE;
1472                                                         break;
1473                                                 case 'x':
1474                                                         val |= AUDIT_PERM_EXEC;
1475                                                         break;
1476                                                 case 'a':
1477                                                         val |= AUDIT_PERM_ATTR;
1478                                                         break;
1479                                                 default:
1480                                                         return -14;
1481                                         }
1482                                 }
1483                                 rule->values[rule->field_count] = val;
1484                         }
1485                         break;
1486                 case AUDIT_FILETYPE:
1487                         if (!(flags == AUDIT_FILTER_EXIT || flags == AUDIT_FILTER_ENTRY))
1488                                 return -17;
1489                         rule->values[rule->field_count] = 
1490                                 audit_name_to_ftype(v);
1491                         if ((int)rule->values[rule->field_count] < 0) {
1492                                 return -16;
1493                         }
1494                         break;
1495                 case AUDIT_ARG0...AUDIT_ARG3:
1496                         vlen = strlen(v);
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] =
1503                                         strtol(v, NULL, 0);
1504                         else 
1505                                 return -21;
1506                         break;
1507                 case AUDIT_DEVMAJOR...AUDIT_INODE:
1508                 case AUDIT_SUCCESS:
1509                         if (flags != AUDIT_FILTER_EXIT)
1510                                 return -7;
1511                         /* fallthrough */
1512                 default:
1513                         if (field == AUDIT_INODE) {
1514                                 if (!(op == AUDIT_NOT_EQUAL ||
1515                                                         op == AUDIT_EQUAL))
1516                                         return -13;
1517                         }
1518
1519                         if (field == AUDIT_PPID && !(flags == AUDIT_FILTER_EXIT
1520                                 || flags == AUDIT_FILTER_ENTRY))
1521                                 return -17;
1522                         
1523                         if (!isdigit((char)*(v)))
1524                                 return -21;
1525
1526                         if (field == AUDIT_INODE)
1527                                 rule->values[rule->field_count] =
1528                                         strtoul(v, NULL, 0);
1529                         else
1530                                 rule->values[rule->field_count] =
1531                                         strtol(v, NULL, 0);
1532                         break;
1533         }
1534         rule->field_count++;
1535         return 0;
1536 }
1537
1538 void audit_rule_free_data(struct audit_rule_data *rule)
1539 {
1540         free(rule);
1541 }
1542
1543 static int audit_name_to_uid(const char *name, uid_t *uid)
1544 {
1545         struct passwd *pw;
1546
1547         pw = getpwnam(name);
1548         if (pw == NULL) 
1549                 return 1;
1550
1551         memset(pw->pw_passwd, ' ', strlen(pw->pw_passwd));
1552         *uid = pw->pw_uid;
1553         return 0;
1554 }
1555
1556 static int audit_name_to_gid(const char *name, gid_t *gid)
1557 {
1558         struct group *gr;
1559
1560         gr = getgrnam(name);
1561         if (gr == NULL) 
1562                 return 1;
1563  
1564         *gid = gr->gr_gid;
1565         return 0;
1566 }
1567
1568 int audit_detect_machine(void)
1569 {
1570         struct utsname uts;
1571         if (uname(&uts) == 0)
1572 //              strcpy(uts.machine, "x86_64");
1573                 return audit_name_to_machine(uts.machine);
1574         return -1;
1575 }
1576 hidden_def(audit_detect_machine)
1577
1578 #ifndef NO_TABLES
1579 void audit_number_to_errmsg(int errnumber, const char *opt)
1580 {
1581         unsigned int i;
1582         
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)
1586                         {
1587                                 case 0:
1588                                         fprintf(stderr, "%s\n",
1589                                                 err_msgtab[i].cvalue);
1590                                         break;
1591                                 case 1:
1592                                         fprintf(stderr, "%s %s\n", opt,
1593                                                 err_msgtab[i].cvalue);
1594                                         break;
1595                                 case 2:
1596                                         fprintf(stderr, "%s %s\n",
1597                                                 err_msgtab[i].cvalue, opt);
1598                                         break;
1599                                 default:
1600                                         break;
1601                         }
1602                         return;
1603                 }
1604         }
1605 }
1606 #endif