PERFORCE change 167246 for review
Ilias Marinos
marinosi at FreeBSD.org
Wed Aug 12 14:14:23 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=167246
Change 167246 by marinosi at marinosi_redrum on 2009/08/12 14:13:59
- Created auditon_slice_internal() function that does all the actual work
for manipulating auditing.
- Modified auditon(2) and auditon_slice(2) to work as wrappers to the previous
function.
- Tested and works (at least with the base trail).
Affected files ...
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit.c#18 edit
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.h#14 edit
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_syscalls.c#11 edit
Differences ...
==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit.c#18 (text) ====
@@ -817,17 +817,8 @@
* never be the base slice as it is not a slice queue element.
*/
int
-audit_slice_destroy(char *as_name)
+audit_slice_destroy(struct audit_slice *as)
{
- int error;
- struct audit_slice *as = NULL;
-
- error = audit_slice_lookup(as_name, as);
- if (error)
- return (1);
-
- if ( as == audit_base_slice )
- return (1); /* Cannot destroy base slice */
AUDIT_SLICES_LOCK();
/*
@@ -946,23 +937,17 @@
/*
* audit_slice_lookup() performs a linear lookup in the audit slices queue
- * bases on the slice name and sets up as to point to the actual slice
- * instance.
- * Returns '0' on success, error code on failure.
+ * based on the slice name.
+ * Returns a ptr to the actual slice on success, NULL if slice is not found.
*/
-int
-audit_slice_lookup(char *as_name, struct audit_slice *as)
+struct audit_slice
+*audit_slice_lookup(char *as_name)
{
- int nbytes;
+
struct audit_slice *cur = NULL;
- nbytes = strlen(as_name);
- if ( nbytes <= 0 || nbytes > AUDIT_SLICE_NAME_LEN )
- return (EINVAL);
-
if ( strcmp(as_name, "audit_base_slice") == 0 ) {
- as = audit_base_slice;
- return (0);
+ return (audit_base_slice);
}
/*
@@ -972,15 +957,478 @@
AUDIT_SLICES_LOCK();
TAILQ_FOREACH(cur, &audit_slice_q, as_q) {
if ( strcmp(cur->as_name, as_name) == 0 ) {
- as = cur;
AUDIT_SLICES_UNLOCK();
- return (0);
+ return (cur);
}
}
/*
* On failure.(slice not found)
*/
- return (1);
+ return (NULL);
+
+}
+
+/*
+ * auditon_slice_internal() performs the actual work for auditon_slice(2) and
+ * auditon(2) system calls.
+ */
+int
+auditon_slice_internal(struct thread *td, int cmd, char *as_name,
+ void *data, u_int length)
+{
+
+ struct audit_slice *as = NULL;
+ struct ucred *cred, *newcred, *oldcred;
+ int error;
+ union auditon_udata udata;
+ struct proc *tp;
+
+ /*
+ * Find the slice we should operate on.
+ */
+ as = audit_slice_lookup(as_name);
+
+ /*
+ * The only way for 'as' to be NULL is when we want to create a new
+ * slice.
+ */
+ if ((as == NULL) && (cmd != A_CREATESLICE))
+ return (EINVAL);
+
+ memset((void *)&udata, 0, sizeof(udata));
+
+ /*
+ * Some of the GET commands use the arguments too.
+ */
+ switch (cmd) {
+ case A_SETPOLICY:
+ case A_OLDSETPOLICY:
+ case A_SETKMASK:
+ case A_SETQCTRL:
+ case A_OLDSETQCTRL:
+ case A_SETSTAT:
+ case A_SETUMASK:
+ case A_SETSMASK:
+ case A_SETCOND:
+ case A_OLDSETCOND:
+ case A_SETCLASS:
+ case A_SETPMASK:
+ case A_SETFSIZE:
+ case A_SETKAUDIT:
+ case A_GETCLASS:
+ case A_GETPINFO:
+ case A_GETPINFO_ADDR:
+ case A_SENDTRIGGER:
+ error = copyin(data, (void *)&udata, length);
+ if (error)
+ return (error);
+ AUDIT_ARG_AUDITON(&udata);
+ break;
+ }
+
+ /*
+ * XXXAUDIT: Locking?
+ */
+ switch (cmd) {
+ case A_OLDGETPOLICY:
+ case A_GETPOLICY:
+ if (length == sizeof(udata.au_policy64)) {
+ if (!as->audit_fail_stop)
+ udata.au_policy64 |= AUDIT_CNT;
+ if (as->audit_panic_on_write_fail)
+ udata.au_policy64 |= AUDIT_AHLT;
+ if (as->audit_argv)
+ udata.au_policy64 |= AUDIT_ARGV;
+ if (as->audit_arge)
+ udata.au_policy64 |= AUDIT_ARGE;
+ break;
+ }
+ if (length != sizeof(udata.au_policy))
+ return (EINVAL);
+ if (!as->audit_fail_stop)
+ udata.au_policy |= AUDIT_CNT;
+ if (as->audit_panic_on_write_fail)
+ udata.au_policy |= AUDIT_AHLT;
+ if (as->audit_argv)
+ udata.au_policy |= AUDIT_ARGV;
+ if (as->audit_arge)
+ udata.au_policy |= AUDIT_ARGE;
+ break;
+
+ case A_OLDSETPOLICY:
+ case A_SETPOLICY:
+ if (length == sizeof(udata.au_policy64)) {
+ if (udata.au_policy & (~AUDIT_CNT|AUDIT_AHLT|
+ AUDIT_ARGV|AUDIT_ARGE))
+ return (EINVAL);
+ as->audit_fail_stop = ((udata.au_policy64
+ & AUDIT_CNT) == 0);
+ as->audit_panic_on_write_fail =
+ (udata.au_policy64 & AUDIT_AHLT);
+ as->audit_argv = (udata.au_policy64
+ & AUDIT_ARGV);
+ as->audit_arge = (udata.au_policy64
+ & AUDIT_ARGE);
+ break;
+ }
+ if (length != sizeof(udata.au_policy))
+ return (EINVAL);
+ if (udata.au_policy & ~(AUDIT_CNT|AUDIT_AHLT|AUDIT_ARGV|
+ AUDIT_ARGE))
+ return (EINVAL);
+ /*
+ * XXX - Need to wake up waiters if the policy relaxes?
+ */
+ as->audit_fail_stop =
+ ((udata.au_policy & AUDIT_CNT) == 0);
+ as->audit_panic_on_write_fail =
+ (udata.au_policy & AUDIT_AHLT);
+ as->audit_argv =
+ (udata.au_policy & AUDIT_ARGV);
+ as->audit_arge =
+ (udata.au_policy & AUDIT_ARGE);
+ break;
+
+ case A_GETKMASK:
+ if (length != sizeof(udata.au_mask))
+ return (EINVAL);
+ udata.au_mask = as->audit_nae_mask;
+ break;
+
+ case A_SETKMASK:
+ if (length != sizeof(udata.au_mask))
+ return (EINVAL);
+ as->audit_nae_mask = udata.au_mask;
+ break;
+
+ case A_OLDGETQCTRL:
+ case A_GETQCTRL:
+ if (length == sizeof(udata.au_qctrl64)) {
+ udata.au_qctrl64.aq64_hiwater =
+ (u_int64_t)as->audit_qctrl.aq_hiwater;
+ udata.au_qctrl64.aq64_lowater =
+ (u_int64_t)as->audit_qctrl.aq_lowater;
+ udata.au_qctrl64.aq64_bufsz =
+ (u_int64_t)as->audit_qctrl.aq_bufsz;
+ udata.au_qctrl64.aq64_minfree =
+ (u_int64_t)as->audit_qctrl.aq_minfree;
+ break;
+ }
+ if (length != sizeof(udata.au_qctrl))
+ return (EINVAL);
+ udata.au_qctrl = as->audit_qctrl;
+ break;
+
+ case A_OLDSETQCTRL:
+ case A_SETQCTRL:
+ if (length == sizeof(udata.au_qctrl64)) {
+ if ((udata.au_qctrl64.aq64_hiwater > AQ_MAXHIGH) ||
+ (udata.au_qctrl64.aq64_lowater >=
+ udata.au_qctrl.aq_hiwater) ||
+ (udata.au_qctrl64.aq64_bufsz > AQ_MAXBUFSZ) ||
+ (udata.au_qctrl64.aq64_minfree < 0) ||
+ (udata.au_qctrl64.aq64_minfree > 100))
+ return (EINVAL);
+ as->audit_qctrl.aq_hiwater =
+ (int)udata.au_qctrl64.aq64_hiwater;
+ as->audit_qctrl.aq_lowater =
+ (int)udata.au_qctrl64.aq64_lowater;
+ as->audit_qctrl.aq_bufsz =
+ (int)udata.au_qctrl64.aq64_bufsz;
+ as->audit_qctrl.aq_minfree =
+ (int)udata.au_qctrl64.aq64_minfree;
+ /* Not used. */
+ as->audit_qctrl.aq_delay = -1;
+ break;
+ }
+ if (length != sizeof(udata.au_qctrl))
+ return (EINVAL);
+ if ((udata.au_qctrl.aq_hiwater > AQ_MAXHIGH) ||
+ (udata.au_qctrl.aq_lowater >= udata.au_qctrl.aq_hiwater) ||
+ (udata.au_qctrl.aq_bufsz > AQ_MAXBUFSZ) ||
+ (udata.au_qctrl.aq_minfree < 0) ||
+ (udata.au_qctrl.aq_minfree > 100))
+ return (EINVAL);
+
+ as->audit_qctrl = udata.au_qctrl;
+ /* XXX The queue delay value isn't used with the kernel. */
+ as->audit_qctrl.aq_delay = -1;
+ break;
+
+ case A_GETCWD:
+ return (ENOSYS);
+ break;
+
+ case A_GETCAR:
+ return (ENOSYS);
+ break;
+
+ case A_GETSTAT:
+ return (ENOSYS);
+ break;
+
+ case A_SETSTAT:
+ return (ENOSYS);
+ break;
+
+ case A_SETUMASK:
+ return (ENOSYS);
+ break;
+
+ case A_SETSMASK:
+ return (ENOSYS);
+ break;
+
+ case A_OLDGETCOND:
+ case A_GETCOND:
+ if (length == sizeof(udata.au_cond64)) {
+ if (as->audit_enabled
+ && !as->audit_suspended)
+ udata.au_cond64 = AUC_AUDITING;
+ else
+ udata.au_cond64 = AUC_NOAUDIT;
+ break;
+ }
+ if (length != sizeof(udata.au_cond))
+ return (EINVAL);
+ if (as->audit_enabled
+ && !as->audit_suspended)
+ udata.au_cond = AUC_AUDITING;
+ else
+ udata.au_cond = AUC_NOAUDIT;
+ break;
+
+ case A_OLDSETCOND:
+ case A_SETCOND:
+ if (length == sizeof(udata.au_cond64)) {
+ if (udata.au_cond64 == AUC_NOAUDIT)
+ as->audit_suspended = 1;
+ if (udata.au_cond64 == AUC_AUDITING)
+ as->audit_suspended = 0;
+ if (udata.au_cond64 == AUC_DISABLED) {
+ as->audit_suspended = 1;
+ audit_shutdown(NULL, 0);
+ }
+ audit_suspended = as->audit_suspended;
+ break;
+ }
+ if (length != sizeof(udata.au_cond))
+ return (EINVAL);
+ if (udata.au_cond == AUC_NOAUDIT)
+ as->audit_suspended = 1;
+ if (udata.au_cond == AUC_AUDITING)
+ as->audit_suspended = 0;
+ if (udata.au_cond == AUC_DISABLED) {
+ as->audit_suspended = 1;
+ audit_shutdown(NULL, 0);
+ }
+ audit_suspended = as->audit_suspended;
+ break;
+
+ case A_GETCLASS:
+ if (length != sizeof(udata.au_evclass))
+ return (EINVAL);
+ udata.au_evclass.ec_class = au_event_class(
+ udata.au_evclass.ec_number);
+ break;
+
+ case A_SETCLASS:
+ if (length != sizeof(udata.au_evclass))
+ return (EINVAL);
+ au_evclassmap_insert(udata.au_evclass.ec_number,
+ udata.au_evclass.ec_class);
+ break;
+
+ case A_GETPINFO:
+ if (length != sizeof(udata.au_aupinfo))
+ return (EINVAL);
+ if (udata.au_aupinfo.ap_pid < 1)
+ return (ESRCH);
+ if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL)
+ return (ESRCH);
+ if ((error = p_cansee(td, tp)) != 0) {
+ PROC_UNLOCK(tp);
+ return (error);
+ }
+ cred = tp->p_ucred;
+ if (cred->cr_audit.ai_termid.at_type == AU_IPv6) {
+ PROC_UNLOCK(tp);
+ return (EINVAL);
+ }
+ udata.au_aupinfo.ap_auid = cred->cr_audit.ai_auid;
+ udata.au_aupinfo.ap_mask.am_success =
+ cred->cr_audit.ai_mask.am_success;
+ udata.au_aupinfo.ap_mask.am_failure =
+ cred->cr_audit.ai_mask.am_failure;
+ udata.au_aupinfo.ap_termid.machine =
+ cred->cr_audit.ai_termid.at_addr[0];
+ udata.au_aupinfo.ap_termid.port =
+ (dev_t)cred->cr_audit.ai_termid.at_port;
+ udata.au_aupinfo.ap_asid = cred->cr_audit.ai_asid;
+ PROC_UNLOCK(tp);
+ break;
+
+ case A_SETPMASK:
+ if (length != sizeof(udata.au_aupinfo))
+ return (EINVAL);
+ if (udata.au_aupinfo.ap_pid < 1)
+ return (ESRCH);
+ newcred = crget();
+ if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) {
+ crfree(newcred);
+ return (ESRCH);
+ }
+ if ((error = p_cansee(td, tp)) != 0) {
+ PROC_UNLOCK(tp);
+ crfree(newcred);
+ return (error);
+ }
+ oldcred = tp->p_ucred;
+ crcopy(newcred, oldcred);
+ newcred->cr_audit.ai_mask.am_success =
+ udata.au_aupinfo.ap_mask.am_success;
+ newcred->cr_audit.ai_mask.am_failure =
+ udata.au_aupinfo.ap_mask.am_failure;
+ td->td_proc->p_ucred = newcred;
+ PROC_UNLOCK(tp);
+ crfree(oldcred);
+ break;
+
+ case A_SETFSIZE:
+ if (length != sizeof(udata.au_fstat))
+ return (EINVAL);
+ if ((udata.au_fstat.af_filesz != 0) &&
+ (udata.au_fstat.af_filesz < MIN_AUDIT_FILE_SIZE))
+ return (EINVAL);
+ as->audit_fstat.af_filesz
+ = udata.au_fstat.af_filesz;
+ break;
+
+ case A_GETFSIZE:
+ if (length != sizeof(udata.au_fstat))
+ return (EINVAL);
+ udata.au_fstat.af_filesz
+ = as->audit_fstat.af_filesz;
+ udata.au_fstat.af_currsz
+ = as->audit_fstat.af_currsz;
+ break;
+
+ case A_GETPINFO_ADDR:
+ if (length != sizeof(udata.au_aupinfo_addr))
+ return (EINVAL);
+ if (udata.au_aupinfo_addr.ap_pid < 1)
+ return (ESRCH);
+ if ((tp = pfind(udata.au_aupinfo_addr.ap_pid)) == NULL)
+ return (ESRCH);
+ cred = tp->p_ucred;
+ udata.au_aupinfo_addr.ap_auid = cred->cr_audit.ai_auid;
+ udata.au_aupinfo_addr.ap_mask.am_success =
+ cred->cr_audit.ai_mask.am_success;
+ udata.au_aupinfo_addr.ap_mask.am_failure =
+ cred->cr_audit.ai_mask.am_failure;
+ udata.au_aupinfo_addr.ap_termid = cred->cr_audit.ai_termid;
+ udata.au_aupinfo_addr.ap_asid = cred->cr_audit.ai_asid;
+ PROC_UNLOCK(tp);
+ break;
+
+ case A_GETKAUDIT:
+ if (length != sizeof(udata.au_kau_info))
+ return (EINVAL);
+ audit_get_kinfo(&udata.au_kau_info);
+ break;
+
+ case A_SETKAUDIT:
+ if (length != sizeof(udata.au_kau_info))
+ return (EINVAL);
+ if (udata.au_kau_info.ai_termid.at_type != AU_IPv4 &&
+ udata.au_kau_info.ai_termid.at_type != AU_IPv6)
+ return (EINVAL);
+ audit_set_kinfo(&udata.au_kau_info);
+ break;
+
+ case A_SENDTRIGGER:
+ if (length != sizeof(udata.au_trigger))
+ return (EINVAL);
+ if ((udata.au_trigger < AUDIT_TRIGGER_MIN) ||
+ (udata.au_trigger > AUDIT_TRIGGER_MAX))
+ return (EINVAL);
+ return (audit_send_trigger(udata.au_trigger));
+
+ /*
+ * XXXRW: as_name use a userspace character array, not a kernel space
+ * string pointer. We need to copyinstr() to a kernel character
+ * array for the purposes of looking it up, etc.
+ * FIXED. Note: Look at auditon_slice(2).
+ *
+ * XXXRW: Possibly audit_slice_*() should be able to return errors--
+ * for example, if there's a name collision on creating slices, or i
+ * a slice can't be found for removal.
+ * FIXED.
+ * With the current implementation, it is not possible to reach to
+ * this point. An error will be returned at the start of this
+ * function.
+ */
+ case A_CREATESLICE:
+ if (length != sizeof(udata.au_slice))
+ return (EINVAL);
+ /* We shouldn't call this command for base slice! */
+ if (as == audit_base_slice)
+ return (EINVAL);
+ /* If slice already exists return an error */
+ if ( as != NULL )
+ return (EEXIST);
+ audit_slice_create(as_name);
+ break;
+
+ case A_UPDATESLICE:
+ if (length != sizeof(udata.au_slice))
+ return (EINVAL);
+ return (0);
+
+ case A_GETSLICE:
+ if (length != sizeof(udata.au_slice))
+ return (EINVAL);
+ return (0);
+
+ case A_REMOVESLICE:
+ if (length != sizeof(udata.au_slice))
+ return (EINVAL);
+ /* We cannot remove base slice! */
+ if (as == audit_base_slice)
+ return (EINVAL);
+ /* Destroy slice */
+ audit_slice_destroy(as);
+ break;
+
+ default:
+ return (EINVAL);
+ }
+
+ /*
+ * Copy data back to userspace for the GET comands.
+ */
+ switch (cmd) {
+ case A_GETPOLICY:
+ case A_OLDGETPOLICY:
+ case A_GETKMASK:
+ case A_GETQCTRL:
+ case A_OLDGETQCTRL:
+ case A_GETCWD:
+ case A_GETCAR:
+ case A_GETSTAT:
+ case A_GETCOND:
+ case A_OLDGETCOND:
+ case A_GETCLASS:
+ case A_GETPINFO:
+ case A_GETFSIZE:
+ case A_GETPINFO_ADDR:
+ case A_GETKAUDIT:
+ error = copyout((void *)&udata, data, length);
+ if (error)
+ return (error);
+ break;
+ }
+ return (0);
}
==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.h#14 (text+ko) ====
@@ -190,9 +190,11 @@
void audit_worker_start(struct audit_slice *as);
void audit_slice_init(struct audit_slice *as, char *name);
void audit_slice_create(char *name);
-int audit_slice_destroy(char *as_name);
+int audit_slice_destroy(struct audit_slice *as);
void audit_slice_cdev_init(struct audit_slice *as);
int audit_slice_commit_rec(void *rec, struct audit_slice *as);
-int audit_slice_lookup(char *as_name, struct audit_slice *as);
+struct audit_slice *audit_slice_lookup(char *as_name);
+int auditon_slice_internal(struct thread *td, int cmd, char *as_name, void *data,
+ u_int length);
#endif /* ! _SECURITY_AUDIT_SLICE_H_ */
==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_syscalls.c#11 (text) ====
@@ -161,8 +161,31 @@
auditon(struct thread *td, struct auditon_args *uap)
{
- /* Dummy syscall -- to be changed */
- return (ENOSYS);
+ int error, ret;
+
+ if (jailed(td->td_ucred))
+ return (ENOSYS);
+ AUDIT_ARG_CMD(uap->cmd);
+
+#ifdef MAC
+ error = mac_system_check_auditon(td->td_ucred, uap->cmd);
+ if (error)
+ return (error);
+#endif
+
+ error = priv_check(td, PRIV_AUDIT_CONTROL);
+ if (error)
+ return (error);
+
+ if ((uap->length <= 0) || (uap->length > sizeof(union auditon_udata)))
+ return (EINVAL);
+
+ /*
+ * auditon(2) always selects audit_base_slice to operate on.
+ */
+ ret = auditon_slice_internal(td, uap->cmd, "audit_base_slice",
+ uap->data, uap->length);
+ return (ret);
}
/*
@@ -172,11 +195,8 @@
int
auditon_slice(struct thread *td, struct auditon_slice_args *uap)
{
- struct ucred *cred, *newcred, *oldcred;
- struct audit_slice *as = NULL;
- int error;
- union auditon_udata udata;
- struct proc *tp;
+
+ int error, ret, nbytes;
char as_name[AUDIT_SLICE_NAME_LEN];
if (jailed(td->td_ucred))
@@ -198,443 +218,23 @@
return (EINVAL);
/*
- * Copyin the name of the slice we need to operate on.
+ * Check slice name.
*/
- error = copyinstr(uap->name, as_name, AUDIT_SLICE_NAME_LEN, NULL);
- if (error)
+ nbytes = strlen(uap->name);
+ if ( nbytes <= 0 || nbytes > AUDIT_SLICE_NAME_LEN )
return (EINVAL);
/*
- * Find the slice we should operate on.
+ * Copyin the name of the slice we need to operate on.
*/
- error = audit_slice_lookup(as_name, as);
+ error = copyinstr(uap->name, as_name, AUDIT_SLICE_NAME_LEN, NULL);
if (error)
- return (error);
-
- memset((void *)&udata, 0, sizeof(udata));
-
- /*
- * Some of the GET commands use the arguments too.
- */
- switch (uap->cmd) {
- case A_SETPOLICY:
- case A_OLDSETPOLICY:
- case A_SETKMASK:
- case A_SETQCTRL:
- case A_OLDSETQCTRL:
- case A_SETSTAT:
- case A_SETUMASK:
- case A_SETSMASK:
- case A_SETCOND:
- case A_OLDSETCOND:
- case A_SETCLASS:
- case A_SETPMASK:
- case A_SETFSIZE:
- case A_SETKAUDIT:
- case A_GETCLASS:
- case A_GETPINFO:
- case A_GETPINFO_ADDR:
- case A_SENDTRIGGER:
- error = copyin(uap->data, (void *)&udata, uap->length);
- if (error)
- return (error);
- AUDIT_ARG_AUDITON(&udata);
- break;
- }
-
- /*
- * XXXAUDIT: Locking?
- */
- switch (uap->cmd) {
- case A_OLDGETPOLICY:
- case A_GETPOLICY:
- if (uap->length == sizeof(udata.au_policy64)) {
- if (!as->audit_fail_stop)
- udata.au_policy64 |= AUDIT_CNT;
- if (as->audit_panic_on_write_fail)
- udata.au_policy64 |= AUDIT_AHLT;
- if (as->audit_argv)
- udata.au_policy64 |= AUDIT_ARGV;
- if (as->audit_arge)
- udata.au_policy64 |= AUDIT_ARGE;
- break;
- }
- if (uap->length != sizeof(udata.au_policy))
- return (EINVAL);
- if (!as->audit_fail_stop)
- udata.au_policy |= AUDIT_CNT;
- if (as->audit_panic_on_write_fail)
- udata.au_policy |= AUDIT_AHLT;
- if (as->audit_argv)
- udata.au_policy |= AUDIT_ARGV;
- if (as->audit_arge)
- udata.au_policy |= AUDIT_ARGE;
- break;
-
- case A_OLDSETPOLICY:
- case A_SETPOLICY:
- if (uap->length == sizeof(udata.au_policy64)) {
- if (udata.au_policy & (~AUDIT_CNT|AUDIT_AHLT|
- AUDIT_ARGV|AUDIT_ARGE))
- return (EINVAL);
- as->audit_fail_stop = ((udata.au_policy64
- & AUDIT_CNT) == 0);
- as->audit_panic_on_write_fail =
- (udata.au_policy64 & AUDIT_AHLT);
- as->audit_argv = (udata.au_policy64
- & AUDIT_ARGV);
- as->audit_arge = (udata.au_policy64
- & AUDIT_ARGE);
- break;
- }
- if (uap->length != sizeof(udata.au_policy))
- return (EINVAL);
- if (udata.au_policy & ~(AUDIT_CNT|AUDIT_AHLT|AUDIT_ARGV|
- AUDIT_ARGE))
- return (EINVAL);
- /*
- * XXX - Need to wake up waiters if the policy relaxes?
- */
- as->audit_fail_stop =
- ((udata.au_policy & AUDIT_CNT) == 0);
- as->audit_panic_on_write_fail =
- (udata.au_policy & AUDIT_AHLT);
- as->audit_argv =
- (udata.au_policy & AUDIT_ARGV);
- as->audit_arge =
- (udata.au_policy & AUDIT_ARGE);
- break;
-
- case A_GETKMASK:
- if (uap->length != sizeof(udata.au_mask))
- return (EINVAL);
- udata.au_mask = as->audit_nae_mask;
- break;
-
- case A_SETKMASK:
- if (uap->length != sizeof(udata.au_mask))
- return (EINVAL);
- as->audit_nae_mask = udata.au_mask;
- break;
-
- case A_OLDGETQCTRL:
- case A_GETQCTRL:
- if (uap->length == sizeof(udata.au_qctrl64)) {
- udata.au_qctrl64.aq64_hiwater =
- (u_int64_t)as->audit_qctrl.aq_hiwater;
- udata.au_qctrl64.aq64_lowater =
- (u_int64_t)as->audit_qctrl.aq_lowater;
- udata.au_qctrl64.aq64_bufsz =
- (u_int64_t)as->audit_qctrl.aq_bufsz;
- udata.au_qctrl64.aq64_minfree =
- (u_int64_t)as->audit_qctrl.aq_minfree;
- break;
- }
- if (uap->length != sizeof(udata.au_qctrl))
- return (EINVAL);
- udata.au_qctrl = as->audit_qctrl;
- break;
-
- case A_OLDSETQCTRL:
- case A_SETQCTRL:
- if (uap->length == sizeof(udata.au_qctrl64)) {
- if ((udata.au_qctrl64.aq64_hiwater > AQ_MAXHIGH) ||
- (udata.au_qctrl64.aq64_lowater >=
- udata.au_qctrl.aq_hiwater) ||
- (udata.au_qctrl64.aq64_bufsz > AQ_MAXBUFSZ) ||
- (udata.au_qctrl64.aq64_minfree < 0) ||
- (udata.au_qctrl64.aq64_minfree > 100))
- return (EINVAL);
- as->audit_qctrl.aq_hiwater =
- (int)udata.au_qctrl64.aq64_hiwater;
- as->audit_qctrl.aq_lowater =
- (int)udata.au_qctrl64.aq64_lowater;
- as->audit_qctrl.aq_bufsz =
- (int)udata.au_qctrl64.aq64_bufsz;
- as->audit_qctrl.aq_minfree =
- (int)udata.au_qctrl64.aq64_minfree;
- /* Not used. */
- as->audit_qctrl.aq_delay = -1;
- break;
- }
- if (uap->length != sizeof(udata.au_qctrl))
- return (EINVAL);
- if ((udata.au_qctrl.aq_hiwater > AQ_MAXHIGH) ||
- (udata.au_qctrl.aq_lowater >= udata.au_qctrl.aq_hiwater) ||
- (udata.au_qctrl.aq_bufsz > AQ_MAXBUFSZ) ||
- (udata.au_qctrl.aq_minfree < 0) ||
- (udata.au_qctrl.aq_minfree > 100))
- return (EINVAL);
-
- as->audit_qctrl = udata.au_qctrl;
- /* XXX The queue delay value isn't used with the kernel. */
- as->audit_qctrl.aq_delay = -1;
- break;
-
- case A_GETCWD:
- return (ENOSYS);
- break;
-
- case A_GETCAR:
- return (ENOSYS);
- break;
-
- case A_GETSTAT:
- return (ENOSYS);
- break;
-
- case A_SETSTAT:
- return (ENOSYS);
- break;
-
- case A_SETUMASK:
- return (ENOSYS);
- break;
-
- case A_SETSMASK:
- return (ENOSYS);
- break;
-
- case A_OLDGETCOND:
- case A_GETCOND:
- if (uap->length == sizeof(udata.au_cond64)) {
- if (as->audit_enabled
- && !as->audit_suspended)
- udata.au_cond64 = AUC_AUDITING;
- else
- udata.au_cond64 = AUC_NOAUDIT;
- break;
- }
- if (uap->length != sizeof(udata.au_cond))
- return (EINVAL);
- if (as->audit_enabled
- && !as->audit_suspended)
- udata.au_cond = AUC_AUDITING;
- else
- udata.au_cond = AUC_NOAUDIT;
- break;
-
- case A_OLDSETCOND:
- case A_SETCOND:
- if (uap->length == sizeof(udata.au_cond64)) {
- if (udata.au_cond64 == AUC_NOAUDIT)
- as->audit_suspended = 1;
- if (udata.au_cond64 == AUC_AUDITING)
- as->audit_suspended = 0;
- if (udata.au_cond64 == AUC_DISABLED) {
- as->audit_suspended = 1;
- audit_shutdown(NULL, 0);
- }
- audit_suspended = as->audit_suspended;
- break;
- }
- if (uap->length != sizeof(udata.au_cond))
- return (EINVAL);
- if (udata.au_cond == AUC_NOAUDIT)
- as->audit_suspended = 1;
- if (udata.au_cond == AUC_AUDITING)
- as->audit_suspended = 0;
- if (udata.au_cond == AUC_DISABLED) {
- as->audit_suspended = 1;
- audit_shutdown(NULL, 0);
- }
- audit_suspended = as->audit_suspended;
- break;
-
- case A_GETCLASS:
- if (uap->length != sizeof(udata.au_evclass))
- return (EINVAL);
- udata.au_evclass.ec_class = au_event_class(
- udata.au_evclass.ec_number);
- break;
-
- case A_SETCLASS:
- if (uap->length != sizeof(udata.au_evclass))
- return (EINVAL);
- au_evclassmap_insert(udata.au_evclass.ec_number,
- udata.au_evclass.ec_class);
- break;
-
- case A_GETPINFO:
- if (uap->length != sizeof(udata.au_aupinfo))
- return (EINVAL);
- if (udata.au_aupinfo.ap_pid < 1)
- return (ESRCH);
- if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL)
- return (ESRCH);
- if ((error = p_cansee(td, tp)) != 0) {
- PROC_UNLOCK(tp);
- return (error);
- }
- cred = tp->p_ucred;
- if (cred->cr_audit.ai_termid.at_type == AU_IPv6) {
- PROC_UNLOCK(tp);
- return (EINVAL);
- }
- udata.au_aupinfo.ap_auid = cred->cr_audit.ai_auid;
- udata.au_aupinfo.ap_mask.am_success =
- cred->cr_audit.ai_mask.am_success;
- udata.au_aupinfo.ap_mask.am_failure =
- cred->cr_audit.ai_mask.am_failure;
- udata.au_aupinfo.ap_termid.machine =
- cred->cr_audit.ai_termid.at_addr[0];
- udata.au_aupinfo.ap_termid.port =
- (dev_t)cred->cr_audit.ai_termid.at_port;
- udata.au_aupinfo.ap_asid = cred->cr_audit.ai_asid;
- PROC_UNLOCK(tp);
- break;
-
- case A_SETPMASK:
- if (uap->length != sizeof(udata.au_aupinfo))
- return (EINVAL);
- if (udata.au_aupinfo.ap_pid < 1)
- return (ESRCH);
- newcred = crget();
- if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) {
- crfree(newcred);
- return (ESRCH);
- }
- if ((error = p_cansee(td, tp)) != 0) {
- PROC_UNLOCK(tp);
- crfree(newcred);
- return (error);
- }
- oldcred = tp->p_ucred;
- crcopy(newcred, oldcred);
- newcred->cr_audit.ai_mask.am_success =
- udata.au_aupinfo.ap_mask.am_success;
- newcred->cr_audit.ai_mask.am_failure =
- udata.au_aupinfo.ap_mask.am_failure;
- td->td_proc->p_ucred = newcred;
- PROC_UNLOCK(tp);
- crfree(oldcred);
- break;
-
- case A_SETFSIZE:
- if (uap->length != sizeof(udata.au_fstat))
- return (EINVAL);
- if ((udata.au_fstat.af_filesz != 0) &&
- (udata.au_fstat.af_filesz < MIN_AUDIT_FILE_SIZE))
- return (EINVAL);
- as->audit_fstat.af_filesz
- = udata.au_fstat.af_filesz;
- break;
-
- case A_GETFSIZE:
- if (uap->length != sizeof(udata.au_fstat))
- return (EINVAL);
- udata.au_fstat.af_filesz
- = as->audit_fstat.af_filesz;
- udata.au_fstat.af_currsz
- = as->audit_fstat.af_currsz;
- break;
-
- case A_GETPINFO_ADDR:
- if (uap->length != sizeof(udata.au_aupinfo_addr))
- return (EINVAL);
- if (udata.au_aupinfo_addr.ap_pid < 1)
- return (ESRCH);
- if ((tp = pfind(udata.au_aupinfo_addr.ap_pid)) == NULL)
- return (ESRCH);
- cred = tp->p_ucred;
- udata.au_aupinfo_addr.ap_auid = cred->cr_audit.ai_auid;
- udata.au_aupinfo_addr.ap_mask.am_success =
- cred->cr_audit.ai_mask.am_success;
- udata.au_aupinfo_addr.ap_mask.am_failure =
- cred->cr_audit.ai_mask.am_failure;
- udata.au_aupinfo_addr.ap_termid = cred->cr_audit.ai_termid;
- udata.au_aupinfo_addr.ap_asid = cred->cr_audit.ai_asid;
- PROC_UNLOCK(tp);
- break;
-
- case A_GETKAUDIT:
- if (uap->length != sizeof(udata.au_kau_info))
- return (EINVAL);
- audit_get_kinfo(&udata.au_kau_info);
- break;
-
- case A_SETKAUDIT:
- if (uap->length != sizeof(udata.au_kau_info))
- return (EINVAL);
- if (udata.au_kau_info.ai_termid.at_type != AU_IPv4 &&
- udata.au_kau_info.ai_termid.at_type != AU_IPv6)
- return (EINVAL);
- audit_set_kinfo(&udata.au_kau_info);
- break;
-
- case A_SENDTRIGGER:
- if (uap->length != sizeof(udata.au_trigger))
- return (EINVAL);
- if ((udata.au_trigger < AUDIT_TRIGGER_MIN) ||
- (udata.au_trigger > AUDIT_TRIGGER_MAX))
- return (EINVAL);
- return (audit_send_trigger(udata.au_trigger));
-
- /*
- * XXXRW: as_name use a userspace character array, not a kernel space
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list