]>
Commit | Line | Data |
---|---|---|
3185942a JA |
1 | Date: Tue, 06 Feb 2007 16:06:58 -0500 |
2 | From: Steve Grubb <sgrubb@redhat.com> | |
3 | Subject: Re: bash and linux audit | |
4 | To: chet.ramey@case.edu | |
5 | Organization: Red Hat | |
6 | ||
7 | OK, I released audit 1.4 Sunday which has the logging function for user | |
8 | commands. It produces audit events like this: | |
9 | ||
10 | type=USER_CMD msg=audit(01/30/2007 18:23:45.793:143) : user pid=22862 uid=root | |
11 | auid=root subj=system_u:system_r:unconfined_t:s0-s0:c0.c1023 | |
12 | msg='cwd=/root/test dir cmd=ls -l (terminal=tty1 res=success)' | |
13 | ||
14 | diff -urp bash-3.2.orig/config-bot.h bash-3.2/config-bot.h | |
15 | --- bash-3.2.orig/config-bot.h 2007-01-03 09:01:05.000000000 -0500 | |
16 | +++ bash-3.2/config-bot.h 2007-01-20 11:59:23.000000000 -0500 | |
17 | @@ -97,6 +97,11 @@ | |
18 | # define RESTRICTED_SHELL_NAME "rbash" | |
19 | #endif | |
20 | ||
21 | +/* If the shell is called by this name, it will become audited. */ | |
22 | +#if defined (AUDIT_SHELL) | |
23 | +# define AUDIT_SHELL_NAME "aubash" | |
24 | +#endif | |
25 | + | |
26 | /***********************************************************/ | |
27 | /* Make sure feature defines have necessary prerequisites. */ | |
28 | /***********************************************************/ | |
29 | diff -urp bash-3.2.orig/config.h.in bash-3.2/config.h.in | |
30 | --- bash-3.2.orig/config.h.in 2007-01-03 09:01:05.000000000 -0500 | |
31 | +++ bash-3.2/config.h.in 2007-01-20 11:59:23.000000000 -0500 | |
32 | @@ -81,6 +81,11 @@ | |
33 | flag. */ | |
34 | #undef RESTRICTED_SHELL | |
35 | ||
36 | +/* Define AUDIT_SHELL if you want the generated shell to audit all | |
37 | + actions performed by root account. The shell thus generated can become | |
38 | + audited by being run with the name "aubash". */ | |
39 | +#undef AUDIT_SHELL | |
40 | + | |
41 | /* Define DISABLED_BUILTINS if you want "builtin foo" to always run the | |
42 | shell builtin "foo", even if it has been disabled with "enable -n foo". */ | |
43 | #undef DISABLED_BUILTINS | |
44 | diff -urp bash-3.2.orig/configure.in bash-3.2/configure.in | |
45 | --- bash-3.2.orig/configure.in 2007-01-03 09:01:05.000000000 -0500 | |
46 | +++ bash-3.2/configure.in 2007-01-20 11:59:23.000000000 -0500 | |
47 | @@ -162,6 +162,7 @@ opt_history=yes | |
48 | opt_bang_history=yes | |
49 | opt_dirstack=yes | |
50 | opt_restricted=yes | |
51 | +opt_audit=yes | |
52 | opt_process_subst=yes | |
53 | opt_prompt_decoding=yes | |
54 | opt_select=yes | |
55 | @@ -195,8 +196,8 @@ dnl a minimal configuration turns everyt | |
56 | dnl added individually | |
57 | if test $opt_minimal_config = yes; then | |
58 | opt_job_control=no opt_alias=no opt_readline=no | |
59 | - opt_history=no opt_bang_history=no opt_dirstack=no | |
60 | - opt_restricted=no opt_process_subst=no opt_prompt_decoding=no | |
61 | + opt_history=no opt_bang_history=no opt_dirstack=no opt_restricted=no | |
62 | + opt_audit=no opt_process_subst=no opt_prompt_decoding=no | |
63 | opt_select=no opt_help=no opt_array_variables=no opt_dparen_arith=no | |
64 | opt_brace_expansion=no opt_disabled_builtins=no opt_command_timing=no | |
65 | opt_extended_glob=no opt_cond_command=no opt_arith_for_command=no | |
66 | @@ -227,6 +228,7 @@ AC_ARG_ENABLE(progcomp, AC_HELP_STRING([ | |
67 | AC_ARG_ENABLE(prompt-string-decoding, AC_HELP_STRING([--enable-prompt-string-decoding], [turn on escape character decoding in prompts]), opt_prompt_decoding=$enableval) | |
68 | AC_ARG_ENABLE(readline, AC_HELP_STRING([--enable-readline], [turn on command line editing]), opt_readline=$enableval) | |
69 | AC_ARG_ENABLE(restricted, AC_HELP_STRING([--enable-restricted], [enable a restricted shell]), opt_restricted=$enableval) | |
70 | +AC_ARG_ENABLE(audit, AC_HELP_STRING([--enable-audit], [enable an audited shell]), opt_audit=$enableval) | |
71 | AC_ARG_ENABLE(select, AC_HELP_STRING([--enable-select], [include select command]), opt_select=$enableval) | |
72 | AC_ARG_ENABLE(separate-helpfiles, AC_HELP_STRING([--enable-separate-helpfiles], [use external files for help builtin documentation]), opt_separate_help=$enableval) | |
73 | AC_ARG_ENABLE(single-help-strings, AC_HELP_STRING([--enable-single-help-strings], [store help documentation as a single string to ease translation]), opt_single_longdoc_strings=$enableval) | |
74 | @@ -254,6 +256,10 @@ fi | |
75 | if test $opt_restricted = yes; then | |
76 | AC_DEFINE(RESTRICTED_SHELL) | |
77 | fi | |
78 | +if test $opt_audit = yes; then | |
79 | +AC_DEFINE(AUDIT_SHELL) | |
80 | +AUDIT_LIB='-laudit' | |
81 | +fi | |
82 | if test $opt_process_subst = yes; then | |
83 | AC_DEFINE(PROCESS_SUBSTITUTION) | |
84 | fi | |
85 | @@ -355,6 +361,8 @@ AC_SUBST(HELPDIRDEFINE) | |
86 | AC_SUBST(HELPINSTALL) | |
87 | AC_SUBST(HELPSTRINGS) | |
88 | ||
89 | +AC_SUBST(AUDIT_LIB) | |
90 | + | |
91 | echo "" | |
92 | echo "Beginning configuration for bash-$BASHVERS-$RELSTATUS for ${host_cpu}-${host_vendor}-${host_os}" | |
93 | echo "" | |
94 | diff -urp bash-3.2.orig/doc/bash.1 bash-3.2/doc/bash.1 | |
95 | --- bash-3.2.orig/doc/bash.1 2007-01-03 09:01:05.000000000 -0500 | |
96 | +++ bash-3.2/doc/bash.1 2007-01-20 11:59:23.000000000 -0500 | |
97 | @@ -155,6 +155,12 @@ single-character options to be recognize | |
98 | .PP | |
99 | .PD 0 | |
100 | .TP | |
101 | +.B \-\-audit | |
102 | +The shell logs all commands run by the root user (see | |
103 | +.SM | |
104 | +.B "AUDIT SHELL" | |
105 | +below). | |
106 | +.TP | |
107 | .B \-\-debugger | |
108 | Arrange for the debugger profile to be executed before the shell | |
109 | starts. | |
110 | @@ -8770,6 +8776,17 @@ turns off any restrictions in the shell | |
111 | script. | |
112 | .\" end of rbash.1 | |
113 | .if \n(zY=1 .ig zY | |
114 | +.SH "AUDIT SHELL" | |
115 | +.zY | |
116 | +.PP | |
117 | +If | |
118 | +.B bash | |
119 | +is started with the name | |
120 | +.BR aubash , | |
121 | +or the | |
122 | +.B \-\-audit | |
123 | +option is supplied at invocation, the shell logs all commands issued by the root user to the audit system. | |
124 | +.if \n(zY=1 .ig zY | |
125 | .SH "SEE ALSO" | |
126 | .PD 0 | |
127 | .TP | |
128 | diff -urp bash-3.2.orig/eval.c bash-3.2/eval.c | |
129 | --- bash-3.2.orig/eval.c 2007-01-03 09:01:06.000000000 -0500 | |
130 | +++ bash-3.2/eval.c 2007-01-20 11:59:23.000000000 -0500 | |
131 | @@ -45,6 +45,11 @@ | |
132 | # include "bashhist.h" | |
133 | #endif | |
134 | ||
135 | +#if defined (AUDIT_SHELL) | |
136 | +# include <libaudit.h> | |
137 | +# include <errno.h> | |
138 | +#endif | |
139 | + | |
140 | extern int EOF_reached; | |
141 | extern int indirection_level; | |
142 | extern int posixly_correct; | |
143 | @@ -58,6 +63,38 @@ extern int rpm_requires; | |
144 | static void send_pwd_to_eterm __P((void)); | |
145 | static sighandler alrm_catcher __P((int)); | |
146 | ||
147 | +#if defined (AUDIT_SHELL) | |
148 | +static int audit_fd = -1; | |
149 | + | |
150 | +static int | |
151 | +audit_start () | |
152 | +{ | |
153 | + audit_fd = audit_open (); | |
154 | + if (audit_fd < 0) | |
155 | + return -1; | |
156 | + else | |
157 | + return 0; | |
158 | +} | |
159 | + | |
160 | +static int | |
161 | +audit (cmd, result) | |
162 | + char *cmd; | |
163 | + int result; | |
164 | +{ | |
165 | + int rc; | |
166 | + | |
167 | + if (audit_fd < 0) | |
168 | + return 0; | |
169 | + | |
170 | + rc = audit_log_user_command (audit_fd, AUDIT_USER_CMD, cmd, | |
171 | + NULL, !result); | |
172 | + close (audit_fd); | |
173 | + audit_fd = -1; | |
174 | + return rc; | |
175 | +} | |
176 | +#endif | |
177 | + | |
178 | + | |
179 | /* Read and execute commands until EOF is reached. This assumes that | |
180 | the input source has already been initialized. */ | |
181 | int | |
182 | @@ -145,7 +182,25 @@ reader_loop () | |
183 | ||
184 | executing = 1; | |
185 | stdin_redir = 0; | |
186 | +#if defined (AUDIT_SHELL) | |
187 | + if (audited && interactive_shell && getuid () == 0) | |
188 | + { | |
189 | + if (audit_start () < 0) | |
190 | + { | |
191 | + if (errno != EINVAL && errno != EPROTONOSUPPORT && | |
192 | + errno != EAFNOSUPPORT) | |
193 | + return EXECUTION_FAILURE; | |
194 | + } | |
195 | + } | |
196 | +#endif | |
197 | + | |
198 | execute_command (current_command); | |
199 | +#if defined (AUDIT_SHELL) | |
200 | + { | |
201 | + extern char *shell_input_line; | |
202 | + audit (shell_input_line, last_command_exit_value); | |
203 | + } | |
204 | +#endif | |
205 | ||
206 | exec_done: | |
207 | QUIT; | |
208 | diff -urp bash-3.2.orig/externs.h bash-3.2/externs.h | |
209 | --- bash-3.2.orig/externs.h 2007-01-03 09:01:06.000000000 -0500 | |
210 | +++ bash-3.2/externs.h 2007-01-20 12:05:00.000000000 -0500 | |
211 | @@ -77,6 +77,10 @@ extern int shell_is_restricted __P((char | |
212 | extern int maybe_make_restricted __P((char *)); | |
213 | #endif | |
214 | ||
215 | +#if defined (AUDIT_SHELL) | |
216 | +extern int maybe_make_audited __P((char *)); | |
217 | +#endif | |
218 | + | |
219 | extern void unset_bash_input __P((int)); | |
220 | extern void get_current_user_info __P((void)); | |
221 | ||
222 | diff -urp bash-3.2.orig/flags.c bash-3.2/flags.c | |
223 | --- bash-3.2.orig/flags.c 2007-01-03 09:01:06.000000000 -0500 | |
224 | +++ bash-3.2/flags.c 2007-01-20 11:59:23.000000000 -0500 | |
225 | @@ -142,6 +142,12 @@ int restricted = 0; /* currently restri | |
226 | int restricted_shell = 0; /* shell was started in restricted mode. */ | |
227 | #endif /* RESTRICTED_SHELL */ | |
228 | ||
229 | +#if defined (AUDIT_SHELL) | |
230 | +/* Non-zero means that this shell is audited. An audited shell records | |
231 | + each command that the root user executes. */ | |
232 | +int audited = 0; /* shell was started in audit mode. */ | |
233 | +#endif /* AUDIT_SHELL */ | |
234 | + | |
235 | /* Non-zero means that this shell is running in `privileged' mode. This | |
236 | is required if the shell is to run setuid. If the `-p' option is | |
237 | not supplied at startup, and the real and effective uids or gids | |
238 | diff -urp bash-3.2.orig/flags.h bash-3.2/flags.h | |
239 | --- bash-3.2.orig/flags.h 2007-01-03 09:01:06.000000000 -0500 | |
240 | +++ bash-3.2/flags.h 2007-01-20 11:59:23.000000000 -0500 | |
241 | @@ -66,6 +66,10 @@ extern int restricted; | |
242 | extern int restricted_shell; | |
243 | #endif /* RESTRICTED_SHELL */ | |
244 | ||
245 | +#if defined (AUDIT_SHELL) | |
246 | +extern int audited; | |
247 | +#endif /* AUDIT_SHELL */ | |
248 | + | |
249 | extern int *find_flag __P((int)); | |
250 | extern int change_flag __P((int, int)); | |
251 | extern char *which_set_flags __P((void)); | |
252 | Only in bash-3.2: .made | |
253 | diff -urp bash-3.2.orig/Makefile.in bash-3.2/Makefile.in | |
254 | --- bash-3.2.orig/Makefile.in 2007-01-03 09:01:06.000000000 -0500 | |
255 | +++ bash-3.2/Makefile.in 2007-01-20 11:59:23.000000000 -0500 | |
256 | @@ -366,6 +366,8 @@ MALLOC_LIBRARY = @MALLOC_LIBRARY@ | |
257 | MALLOC_LDFLAGS = @MALLOC_LDFLAGS@ | |
258 | MALLOC_DEP = @MALLOC_DEP@ | |
259 | ||
260 | +AUDIT_LIB = @AUDIT_LIB@ | |
261 | + | |
262 | ALLOC_HEADERS = $(ALLOC_LIBSRC)/getpagesize.h $(ALLOC_LIBSRC)/shmalloc.h \ | |
263 | $(ALLOC_LIBSRC)/imalloc.h $(ALLOC_LIBSRC)/mstats.h \ | |
264 | $(ALLOC_LIBSRC)/table.h $(ALLOC_LIBSRC)/watch.h | |
265 | @@ -386,7 +388,7 @@ BASHINCFILES = $(BASHINCDIR)/posixstat. | |
266 | $(BASHINCDIR)/ocache.h | |
267 | ||
268 | LIBRARIES = $(SHLIB_LIB) $(READLINE_LIB) $(HISTORY_LIB) $(TERMCAP_LIB) $(GLOB_LIB) \ | |
269 | - $(TILDE_LIB) $(MALLOC_LIB) $(INTL_LIB) $(LOCAL_LIBS) | |
270 | + $(TILDE_LIB) $(MALLOC_LIB) $(INTL_LIB) $(LOCAL_LIBS) $(AUDIT_LIB) | |
271 | ||
272 | LIBDEP = $(SHLIB_DEP) $(INTL_DEP) $(READLINE_DEP) $(HISTORY_DEP) $(TERMCAP_DEP) $(GLOB_DEP) \ | |
273 | $(TILDE_DEP) $(MALLOC_DEP) | |
274 | diff -urp bash-3.2.orig/parse.y bash-3.2/parse.y | |
275 | --- bash-3.2.orig/parse.y 2007-01-03 09:01:06.000000000 -0500 | |
276 | +++ bash-3.2/parse.y 2007-01-20 11:59:23.000000000 -0500 | |
277 | @@ -258,7 +258,7 @@ int need_here_doc; | |
278 | ||
279 | /* Where shell input comes from. History expansion is performed on each | |
280 | line when the shell is interactive. */ | |
281 | -static char *shell_input_line = (char *)NULL; | |
282 | +char *shell_input_line = (char *)NULL; | |
283 | static int shell_input_line_index; | |
284 | static int shell_input_line_size; /* Amount allocated for shell_input_line. */ | |
285 | static int shell_input_line_len; /* strlen (shell_input_line) */ | |
286 | diff -urp bash-3.2.orig/shell.c bash-3.2/shell.c | |
287 | --- bash-3.2.orig/shell.c 2007-01-03 09:01:06.000000000 -0500 | |
288 | +++ bash-3.2/shell.c 2007-01-20 12:04:23.000000000 -0500 | |
289 | @@ -240,6 +240,9 @@ struct { | |
290 | #if defined (RESTRICTED_SHELL) | |
291 | { "restricted", Int, &restricted, (char **)0x0 }, | |
292 | #endif | |
293 | +#if defined (AUDIT_SHELL) | |
294 | + { "audit", Int, &audited, (char **)0x0 }, | |
295 | +#endif | |
296 | { "verbose", Int, &echo_input_at_read, (char **)0x0 }, | |
297 | { "version", Int, &do_version, (char **)0x0 }, | |
298 | { "wordexp", Int, &wordexp_only, (char **)0x0 }, | |
299 | @@ -644,6 +647,10 @@ main (argc, argv, env) | |
300 | maybe_make_restricted (shell_name); | |
301 | #endif /* RESTRICTED_SHELL */ | |
302 | ||
303 | +#if defined (AUDIT_SHELL) | |
304 | + maybe_make_audited (shell_name); | |
305 | +#endif | |
306 | + | |
307 | if (wordexp_only) | |
308 | { | |
309 | startup_state = 3; | |
310 | @@ -1143,6 +1150,29 @@ maybe_make_restricted (name) | |
311 | } | |
312 | #endif /* RESTRICTED_SHELL */ | |
313 | ||
314 | +#if defined (AUDIT_SHELL) | |
315 | +/* Perhaps make this shell an `audited' one, based on NAME. If the | |
316 | + basename of NAME is "aubash", then this shell is audited. The | |
317 | + name of the audited shell is a configurable option, see config.h. | |
318 | + In an audited shell, all actions performed by root will be logged | |
319 | + to the audit system. | |
320 | + Do this also if `audited' is already set to 1 maybe the shell was | |
321 | + started with --audit. */ | |
322 | +int | |
323 | +maybe_make_audited (name) | |
324 | + char *name; | |
325 | +{ | |
326 | + char *temp; | |
327 | + | |
328 | + temp = base_pathname (name); | |
329 | + if (*temp == '-') | |
330 | + temp++; | |
331 | + if (audited || (STREQ (temp, AUDIT_SHELL_NAME))) | |
332 | + audited = 1; | |
333 | + return (audited); | |
334 | +} | |
335 | +#endif /* AUDIT_SHELL */ | |
336 | + | |
337 | /* Fetch the current set of uids and gids and return 1 if we're running | |
338 | setuid or setgid. */ | |
339 | static int |