From owner-p4-projects@FreeBSD.ORG Fri May 5 16:11:28 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7B36516A402; Fri, 5 May 2006 16:11:28 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5075416A400 for ; Fri, 5 May 2006 16:11:28 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9D87E43D55 for ; Fri, 5 May 2006 16:11:25 +0000 (GMT) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k45GBPfT030766 for ; Fri, 5 May 2006 16:11:25 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k45GBPFX030758 for perforce@freebsd.org; Fri, 5 May 2006 16:11:25 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Fri, 5 May 2006 16:11:25 GMT Message-Id: <200605051611.k45GBPFX030758@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Cc: Subject: PERFORCE change 96706 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 May 2006 16:11:28 -0000 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;