PERFORCE change 96706 for review
Robert Watson
rwatson at FreeBSD.org
Fri May 5 16:17:44 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=96706
Change 96706 by rwatson at rwatson_zoo on 2006/05/05 16:11:23
First pass implementations of get / set / delete / flush auid
preselection rules. Not tested.
Rename auditpipe_preselect to auditpipe_ioctl_preselect as an
ioctl argument to prevent excessively similar name to
audit_pipe_preselect. It's still not a very good structure name,
as the string 'auid' should probably appear in it.
Add better locking for various ioctls.
Affected files ...
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_ioctl.h#10 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_pipe.c#20 edit
Differences ...
==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_ioctl.h#10 (text+ko) ====
@@ -38,9 +38,9 @@
* structures, add new revised ones to be used by new ioctls, and keep the
* old structures and ioctls for backwards compatibility.
*/
-struct auditpipe_preselect {
- au_id_t ap_auid;
- au_mask_t ap_mask;
+struct auditpipe_ioctl_preselect {
+ au_id_t aip_auid;
+ au_mask_t aip_mask;
};
/*
@@ -56,9 +56,9 @@
#define AUDITPIPE_GET_PRESELECT_NAFLAGS _IOR(AUDITPIPE_IOBASE, 8, au_mask_t)
#define AUDITPIPE_SET_PRESELECT_NAFLAGS _IOW(AUDITPIPE_IOBASE, 9, au_mask_t)
#define AUDITPIPE_GET_PRESELECT_AUID _IOR(AUDITPIPE_IOBASE, 10, \
- struct auditpipe_preselect)
+ struct auditpipe_ioctl_preselect)
#define AUDITPIPE_SET_PRESELECT_AUID _IOW(AUDITPIPE_IOBASE, 11, \
- struct auditpipe_preselect)
+ struct auditpipe_ioctl_preselect)
#define AUDITPIPE_DELETE_PRESELECT_AUID _IOW(AUDITPIPE_IOBASE, 12, au_id_t)
#define AUDITPIPE_FLUSH_PRESELECT_AUID _IO(AUDITPIPE_IOBASE, 13)
#define AUDITPIPE_GET_PRESELECT_TRAIL _IOR(AUDITPIPE_IOBASE, 14, int)
==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_pipe.c#20 (text+ko) ====
@@ -200,6 +200,97 @@
}
/*
+ * Find an audit pipe preselection specification for an auid, if any.
+ */
+static struct audit_pipe_preselect *
+audit_pipe_preselect_find(struct audit_pipe *ap, au_id_t auid)
+{
+ struct audit_pipe_preselect *app;
+
+ mtx_assert(&audit_pipe_mtx, MA_OWNED);
+
+ TAILQ_FOREACH(app, &ap->ap_preselect_list, app_list) {
+ if (app->app_auid == auid)
+ return (app);
+ }
+ return (NULL);
+}
+
+static int
+audit_pipe_preselect_get(struct audit_pipe *ap, au_id_t auid,
+ au_mask_t *maskp)
+{
+ struct audit_pipe_preselect *app;
+ int error;
+
+ mtx_lock(&audit_pipe_mtx);
+ app = audit_pipe_preselect_find(ap, auid);
+ if (app != NULL) {
+ *maskp = app->app_mask;
+ error = 0;
+ } else
+ error = ENOENT;
+ mtx_unlock(&audit_pipe_mtx);
+ return (error);
+}
+
+static void
+audit_pipe_preselect_set(struct audit_pipe *ap, au_id_t auid, au_mask_t mask)
+{
+ struct audit_pipe_preselect *app, *app_new;
+
+ /*
+ * Pessimistically assume that the auid doesn't already have a mask
+ * set, and allocate. We will free it if it is unneeded.
+ */
+ app_new = malloc(sizeof(*app_new), M_AUDIT_PIPE_PRESELECT, M_WAITOK);
+ mtx_lock(&audit_pipe_mtx);
+ app = audit_pipe_preselect_find(ap, auid);
+ if (app == NULL) {
+ app = app_new;
+ app_new = NULL;
+ app->app_auid = auid;
+ TAILQ_INSERT_TAIL(&ap->ap_preselect_list, app, app_list);
+ }
+ app->app_mask = mask;
+ mtx_unlock(&audit_pipe_mtx);
+ if (app_new != NULL)
+ free(app_new, M_AUDIT_PIPE_PRESELECT);
+}
+
+static int
+audit_pipe_preselect_delete(struct audit_pipe *ap, au_id_t auid)
+{
+ struct audit_pipe_preselect *app;
+ int error;
+
+ mtx_lock(&audit_pipe_mtx);
+ app = audit_pipe_preselect_find(ap, auid);
+ if (app != NULL) {
+ TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list);
+ error = 0;
+ } else
+ error = ENOENT;
+ mtx_unlock(&audit_pipe_mtx);
+ if (app != NULL)
+ free(app, M_AUDIT_PIPE_PRESELECT);
+ return (error);
+}
+
+static void
+audit_pipe_preselect_flush(struct audit_pipe *ap)
+{
+ struct audit_pipe_preselect *app;
+
+ mtx_lock(&audit_pipe_mtx);
+ while ((app = TAILQ_FIRST(&ap->ap_preselect_list)) != NULL) {
+ TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list);
+ free(app, M_AUDIT_PIPE_PRESELECT);
+ }
+ mtx_unlock(&audit_pipe_mtx);
+}
+
+/*
* Determine whether a specific audit pipe matches a record with these
* properties. Algorithm is as follows:
*
@@ -220,10 +311,7 @@
if ((ap->ap_flags & AUDIT_PIPE_TRAIL) && trail_preselect)
return (1);
- TAILQ_FOREACH(app, &ap->ap_preselect_list, app_list) {
- if (app->app_auid == auid)
- break;
- }
+ app = audit_pipe_preselect_find(ap, auid);
if (app == NULL) {
if (auid == AU_DEFAUDITID)
return (au_preselect(event, class,
@@ -539,7 +627,7 @@
audit_pipe_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
struct thread *td)
{
- struct auditpipe_preselect *aps;
+ struct auditpipe_ioctl_preselect *aip;
struct audit_pipe *ap;
au_mask_t *maskp;
au_id_t auid;
@@ -625,63 +713,80 @@
break;
case AUDITPIPE_GET_PRESELECT_FLAGS:
+ mtx_lock(&audit_pipe_mtx);
maskp = (au_mask_t *)data;
*maskp = ap->ap_preselect_flags;
+ mtx_unlock(&audit_pipe_mtx);
error = 0;
break;
case AUDITPIPE_SET_PRESELECT_FLAGS:
+ mtx_lock(&audit_pipe_mtx);
maskp = (au_mask_t *)data;
ap->ap_preselect_flags = *maskp;
+ mtx_unlock(&audit_pipe_mtx);
error = 0;
break;
case AUDITPIPE_GET_PRESELECT_NAFLAGS:
+ mtx_lock(&audit_pipe_mtx);
maskp = (au_mask_t *)data;
*maskp = ap->ap_preselect_naflags;
+ mtx_unlock(&audit_pipe_mtx);
error = 0;
break;
case AUDITPIPE_SET_PRESELECT_NAFLAGS:
+ mtx_lock(&audit_pipe_mtx);
maskp = (au_mask_t *)data;
ap->ap_preselect_naflags = *maskp;
+ mtx_unlock(&audit_pipe_mtx);
error = 0;
break;
case AUDITPIPE_GET_PRESELECT_AUID:
- aps = (struct auditpipe_preselect *)data;
- error = EOPNOTSUPP;
+ aip = (struct auditpipe_ioctl_preselect *)data;
+ error = audit_pipe_preselect_get(ap, aip->aip_auid,
+ &aip->aip_mask);
break;
case AUDITPIPE_SET_PRESELECT_AUID:
- aps = (struct auditpipe_preselect *)data;
- error = EOPNOTSUPP;
+ aip = (struct auditpipe_ioctl_preselect *)data;
+ audit_pipe_preselect_set(ap, aip->aip_auid, aip->aip_mask);
+ error = 0;
break;
case AUDITPIPE_DELETE_PRESELECT_AUID:
auid = *(au_id_t *)data;
- error = EOPNOTSUPP;
+ error = audit_pipe_preselect_delete(ap, auid);
break;
case AUDITPIPE_FLUSH_PRESELECT_AUID:
- error = EOPNOTSUPP;
+ audit_pipe_preselect_flush(ap);
+ error = 0;
break;
case AUDITPIPE_GET_PRESELECT_TRAIL:
+ mtx_lock(&audit_pipe_mtx);
*(int *)data = (ap->ap_flags & AUDIT_PIPE_TRAIL) ? 1 : 0;
+ mtx_unlock(&audit_pipe_mtx);
error = 0;
break;
case AUDITPIPE_SET_PRESELECT_TRAIL:
+ mtx_lock(&audit_pipe_mtx);
if (*(int *)data)
ap->ap_flags |= AUDIT_PIPE_TRAIL;
else
ap->ap_flags &= ~AUDIT_PIPE_TRAIL;
+ mtx_unlock(&audit_pipe_mtx);
error = 0;
break;
case AUDITPIPE_FLUSH:
+ mtx_lock(&audit_pipe_mtx);
audit_pipe_flush(ap);
+ mtx_unlock(&audit_pipe_mtx);
error = 0;
break;
More information about the trustedbsd-cvs
mailing list