Date: Fri, 5 May 2006 16:11:25 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 96706 for review Message-ID: <200605051611.k45GBPFX030758@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=96706 Change 96706 by rwatson@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200605051611.k45GBPFX030758>