audit.c revision 302408
1/*-
2 * Copyright (c) 2005-2009 Apple Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1.  Redistributions of source code must retain the above copyright
10 *     notice, this list of conditions and the following disclaimer.
11 * 2.  Redistributions in binary form must reproduce the above copyright
12 *     notice, this list of conditions and the following disclaimer in the
13 *     documentation and/or other materials provided with the distribution.
14 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15 *     its contributors may be used to endorse or promote products derived
16 *     from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29/*
30 * Program to trigger the audit daemon with a message that is either:
31 *    - Open a new audit log file
32 *    - Read the audit control file and take action on it
33 *    - Close the audit log file and exit
34 *
35 */
36
37#include <sys/types.h>
38#include <config/config.h>
39#ifdef HAVE_FULL_QUEUE_H
40#include <sys/queue.h>
41#else /* !HAVE_FULL_QUEUE_H */
42#include <compat/queue.h>
43#endif /* !HAVE_FULL_QUEUE_H */
44#include <sys/uio.h>
45
46#include <bsm/libbsm.h>
47
48#include <errno.h>
49#include <fcntl.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <unistd.h>
53
54
55static int send_trigger(int);
56
57#ifdef USE_MACH_IPC
58#include <mach/mach.h>
59#include <servers/netname.h>
60#include <mach/message.h>
61#include <mach/port.h>
62#include <mach/mach_error.h>
63#include <mach/host_special_ports.h>
64#include <servers/bootstrap.h>
65
66#include "auditd_control.h"
67
68/*
69 * XXX The following are temporary until these can be added to the kernel
70 * audit.h header.
71 */
72#ifndef AUDIT_TRIGGER_INITIALIZE
73#define	AUDIT_TRIGGER_INITIALIZE	7
74#endif
75#ifndef AUDIT_TRIGGER_EXPIRE_TRAILS
76#define	AUDIT_TRIGGER_EXPIRE_TRAILS	8
77#endif
78
79static int
80send_trigger(int trigger)
81{
82	mach_port_t     serverPort;
83	kern_return_t	error;
84
85	error = host_get_audit_control_port(mach_host_self(), &serverPort);
86	if (error != KERN_SUCCESS) {
87		if (geteuid() != 0) {
88			errno = EPERM;
89			perror("audit requires root privileges");
90		} else
91			mach_error("Cannot get auditd_control Mach port:",
92			    error);
93		return (-1);
94	}
95
96	error = auditd_control(serverPort, trigger);
97	if (error != KERN_SUCCESS) {
98		mach_error("Error sending trigger: ", error);
99		return (-1);
100	}
101
102	return (0);
103}
104
105#else /* ! USE_MACH_IPC */
106
107static int
108send_trigger(int trigger)
109{
110	int error;
111
112	error = audit_send_trigger(&trigger);
113	if (error != 0) {
114		if (error == EPERM)
115			perror("audit requires root privileges");
116		else
117			perror("Error sending trigger");
118		return (-1);
119	}
120
121	return (0);
122}
123#endif /* ! USE_MACH_IPC */
124
125static void
126usage(void)
127{
128
129	(void)fprintf(stderr, "Usage: audit -e | -i | -n | -s | -t \n");
130	exit(-1);
131}
132
133/*
134 * Main routine to process command line options.
135 */
136int
137main(int argc, char **argv)
138{
139	int ch;
140	unsigned int trigger = 0;
141
142	if (argc != 2)
143		usage();
144
145	while ((ch = getopt(argc, argv, "einst")) != -1) {
146		switch(ch) {
147
148		case 'e':
149			trigger = AUDIT_TRIGGER_EXPIRE_TRAILS;
150			break;
151
152		case 'i':
153			trigger = AUDIT_TRIGGER_INITIALIZE;
154			break;
155
156		case 'n':
157			trigger = AUDIT_TRIGGER_ROTATE_USER;
158			break;
159
160		case 's':
161			trigger = AUDIT_TRIGGER_READ_FILE;
162			break;
163
164		case 't':
165			trigger = AUDIT_TRIGGER_CLOSE_AND_DIE;
166			break;
167
168		case '?':
169		default:
170			usage();
171			break;
172		}
173	}
174	if (send_trigger(trigger) < 0)
175		exit(-1);
176
177	printf("Trigger sent.\n");
178	exit (0);
179}
180