1185573Srwatson/*-
2189279Srwatson * Copyright (c) 2005-2009 Apple Inc.
3155131Srwatson * All rights reserved.
4155131Srwatson *
5155131Srwatson * Redistribution and use in source and binary forms, with or without
6155131Srwatson * modification, are permitted provided that the following conditions
7155131Srwatson * are met:
8155131Srwatson *
9155131Srwatson * 1.  Redistributions of source code must retain the above copyright
10155131Srwatson *     notice, this list of conditions and the following disclaimer.
11155131Srwatson * 2.  Redistributions in binary form must reproduce the above copyright
12155131Srwatson *     notice, this list of conditions and the following disclaimer in the
13155131Srwatson *     documentation and/or other materials provided with the distribution.
14185573Srwatson * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15155131Srwatson *     its contributors may be used to endorse or promote products derived
16155131Srwatson *     from this software without specific prior written permission.
17155131Srwatson *
18155131Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19155131Srwatson * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20155131Srwatson * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21155131Srwatson * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22155131Srwatson * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23155131Srwatson * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24155131Srwatson * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25155131Srwatson * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26155131Srwatson * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27155131Srwatson * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28155131Srwatson */
29155131Srwatson/*
30155131Srwatson * Program to trigger the audit daemon with a message that is either:
31155131Srwatson *    - Open a new audit log file
32155131Srwatson *    - Read the audit control file and take action on it
33155131Srwatson *    - Close the audit log file and exit
34155131Srwatson *
35155131Srwatson */
36155131Srwatson
37155518Srwatson#include <sys/types.h>
38185573Srwatson#include <config/config.h>
39185573Srwatson#ifdef HAVE_FULL_QUEUE_H
40155131Srwatson#include <sys/queue.h>
41185573Srwatson#else /* !HAVE_FULL_QUEUE_H */
42185573Srwatson#include <compat/queue.h>
43185573Srwatson#endif /* !HAVE_FULL_QUEUE_H */
44155131Srwatson#include <sys/uio.h>
45155131Srwatson
46156283Srwatson#include <bsm/libbsm.h>
47155131Srwatson
48186647Srwatson#include <errno.h>
49155131Srwatson#include <fcntl.h>
50155131Srwatson#include <stdio.h>
51155131Srwatson#include <stdlib.h>
52155131Srwatson#include <unistd.h>
53155131Srwatson
54185573Srwatson
55191273Srwatsonstatic int send_trigger(int);
56185573Srwatson
57185573Srwatson#ifdef USE_MACH_IPC
58185573Srwatson#include <mach/mach.h>
59185573Srwatson#include <servers/netname.h>
60185573Srwatson#include <mach/message.h>
61185573Srwatson#include <mach/port.h>
62185573Srwatson#include <mach/mach_error.h>
63185573Srwatson#include <mach/host_special_ports.h>
64185573Srwatson#include <servers/bootstrap.h>
65185573Srwatson
66186647Srwatson#include "auditd_control.h"
67185573Srwatson
68186647Srwatson/*
69189279Srwatson * XXX The following are temporary until these can be added to the kernel
70186647Srwatson * audit.h header.
71186647Srwatson */
72186647Srwatson#ifndef AUDIT_TRIGGER_INITIALIZE
73186647Srwatson#define	AUDIT_TRIGGER_INITIALIZE	7
74186647Srwatson#endif
75189279Srwatson#ifndef AUDIT_TRIGGER_EXPIRE_TRAILS
76189279Srwatson#define	AUDIT_TRIGGER_EXPIRE_TRAILS	8
77189279Srwatson#endif
78186647Srwatson
79185573Srwatsonstatic int
80191273Srwatsonsend_trigger(int trigger)
81185573Srwatson{
82185573Srwatson	mach_port_t     serverPort;
83185573Srwatson	kern_return_t	error;
84185573Srwatson
85185573Srwatson	error = host_get_audit_control_port(mach_host_self(), &serverPort);
86185573Srwatson	if (error != KERN_SUCCESS) {
87186647Srwatson		if (geteuid() != 0) {
88186647Srwatson			errno = EPERM;
89186647Srwatson			perror("audit requires root privileges");
90186647Srwatson		} else
91186647Srwatson			mach_error("Cannot get auditd_control Mach port:",
92186647Srwatson			    error);
93185573Srwatson		return (-1);
94185573Srwatson	}
95185573Srwatson
96185573Srwatson	error = auditd_control(serverPort, trigger);
97185573Srwatson	if (error != KERN_SUCCESS) {
98185573Srwatson		mach_error("Error sending trigger: ", error);
99185573Srwatson		return (-1);
100185573Srwatson	}
101185573Srwatson
102185573Srwatson	return (0);
103185573Srwatson}
104185573Srwatson
105185573Srwatson#else /* ! USE_MACH_IPC */
106185573Srwatson
107185573Srwatsonstatic int
108191273Srwatsonsend_trigger(int trigger)
109185573Srwatson{
110185573Srwatson	int error;
111185573Srwatson
112191273Srwatson	error = audit_send_trigger(&trigger);
113185573Srwatson	if (error != 0) {
114186647Srwatson		if (error == EPERM)
115186647Srwatson			perror("audit requires root privileges");
116186647Srwatson		else
117186647Srwatson			perror("Error sending trigger");
118185573Srwatson		return (-1);
119185573Srwatson	}
120185573Srwatson
121185573Srwatson	return (0);
122185573Srwatson}
123185573Srwatson#endif /* ! USE_MACH_IPC */
124185573Srwatson
125155131Srwatsonstatic void
126155131Srwatsonusage(void)
127155131Srwatson{
128155131Srwatson
129189279Srwatson	(void)fprintf(stderr, "Usage: audit -e | -i | -n | -s | -t \n");
130155131Srwatson	exit(-1);
131155131Srwatson}
132155131Srwatson
133155131Srwatson/*
134155131Srwatson * Main routine to process command line options.
135155131Srwatson */
136155131Srwatsonint
137155131Srwatsonmain(int argc, char **argv)
138155131Srwatson{
139155364Srwatson	int ch;
140155131Srwatson	unsigned int trigger = 0;
141155131Srwatson
142155131Srwatson	if (argc != 2)
143155131Srwatson		usage();
144155131Srwatson
145189279Srwatson	while ((ch = getopt(argc, argv, "einst")) != -1) {
146155131Srwatson		switch(ch) {
147155131Srwatson
148189279Srwatson		case 'e':
149189279Srwatson			trigger = AUDIT_TRIGGER_EXPIRE_TRAILS;
150189279Srwatson			break;
151189279Srwatson
152186647Srwatson		case 'i':
153186647Srwatson			trigger = AUDIT_TRIGGER_INITIALIZE;
154186647Srwatson			break;
155186647Srwatson
156155131Srwatson		case 'n':
157162503Srwatson			trigger = AUDIT_TRIGGER_ROTATE_USER;
158155131Srwatson			break;
159155131Srwatson
160155131Srwatson		case 's':
161155131Srwatson			trigger = AUDIT_TRIGGER_READ_FILE;
162155131Srwatson			break;
163155131Srwatson
164155131Srwatson		case 't':
165155131Srwatson			trigger = AUDIT_TRIGGER_CLOSE_AND_DIE;
166155131Srwatson			break;
167155131Srwatson
168155131Srwatson		case '?':
169155131Srwatson		default:
170155131Srwatson			usage();
171155131Srwatson			break;
172155131Srwatson		}
173155131Srwatson	}
174185573Srwatson	if (send_trigger(trigger) < 0)
175155131Srwatson		exit(-1);
176185573Srwatson
177185573Srwatson	printf("Trigger sent.\n");
178185573Srwatson	exit (0);
179155131Srwatson}
180