8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * The Secure SunOS audit reduction tool - auditreduce.
29 * Document SM0071 is the primary source of information on auditreduce.
30 *
31 * Composed of 4 source modules:
32 * main.c - main driver.
33 * option.c - command line option processing.
34 * process.c - record/file/process functions.
35 * time.c - date/time handling.
36 *
37 * Main(), write_header(), audit_stats(), and a_calloc()
38 * are the only functions visible outside this module.
39 */
40
41 #include <siginfo.h>
42 #include <locale.h>
43 #include <libintl.h>
44 #include "auditr.h"
45 #include "auditrd.h"
46
47 #if !defined(TEXT_DOMAIN)
230 a_calloc(tofork, sizeof (*pcb));
231 nnsp = nsp / tofork; /* # of pcbs per forked process */
232 nrem = nsp % tofork; /* remainder to spread around */
233 /*
234 * Loop to fork all of the subs. Open a pipe for each.
235 * If there are any errors in pipes, forks, or getting streams
236 * for the pipes then quit altogether.
237 */
238 for (i = 0; i < tofork; i++) {
239 pcbn = &pcb->pcb_below[i];
240 pcbn->pcb_time = -1;
241 if (pipe(fildes)) {
242 perror(gettext(
243 "auditreduce: couldn't get a pipe"));
244 return (-1);
245 }
246 /*
247 * Convert descriptors to streams.
248 */
249 if ((pcbn->pcb_fpr = fdopen(fildes[0], "r")) == NULL) {
250 perror(gettext("auditreduce: couldn't get read stream for pipe"));
251 return (-1);
252 }
253 if ((pcbn->pcb_fpw = fdopen(fildes[1], "w")) == NULL) {
254 perror(gettext("auditreduce: couldn't get write stream for pipe"));
255 return (-1);
256 }
257 if ((procno = fork()) == -1) {
258 perror(gettext("auditreduce: fork failed"));
259 return (-1);
260 }
261 /*
262 * Calculate the range of pcbs from audit_pcbs [] this
263 * branch of the tree will be responsible for.
264 */
265 range = (nrem > 0) ? nnsp + 1 : nnsp;
266 /*
267 * Child route.
268 */
269 if (procno == 0) {
270 pcbn->pcb_procno = getpid();
271 c_close(pcb, i); /* close unused streams */
272 /*
273 * Continue resolving this branch.
274 */
383 * It also closes the read streams for the other children that
384 * have been born before it. If any closes fail a warning message
385 * is printed, but processing continues.
386 * .call ret = c_close(pcb, i).
387 * .arg pcb - ptr to the child's parent pcb.
388 * .arg i - iteration # of child in forking loop.
389 * .ret void.
390 */
391 static void
392 c_close(audit_pcb_t *pcb, int i)
393 {
394 int j;
395 audit_pcb_t *pcbt;
396
397 /*
398 * Do all pcbs in parent's group up to and including us
399 */
400 for (j = 0; j <= i; j++) {
401 pcbt = &pcb->pcb_below[j];
402 if (fclose(pcbt->pcb_fpr) == EOF) {
403 if (!f_quiet)
404 perror(gettext("auditreduce: initial close on pipe failed"));
405 }
406 /*
407 * Free the buffer allocated to hold incoming records.
408 */
409 if (i != j) {
410 free(pcbt->pcb_rec);
411 }
412 }
413 }
414
415
416 /*
417 * .func p_close - close unused streams for parent.
418 * .desc Called by the parent right after forking a child.
419 * Closes the write stream on the pipe to the child since
420 * we will never use it.
421 * .call p_close(pcbn),
422 * .arg pcbn - ptr to pcb.
423 * .ret void.
424 */
425 static void
426 p_close(audit_pcb_t *pcbn)
427 {
428 if (fclose(pcbn->pcb_fpw) == EOF) {
429 if (!f_quiet)
430 perror(gettext("auditreduce: close for write pipe failed"));
431 }
432 }
433
434
435 /*
436 * .func audit_stats - print statistics.
437 * .desc Print usage statistics for the user if the run fails.
438 * Tells them how many files they had and how many groups this
439 * totalled. Also tell them how many layers and processes the
440 * process tree had.
441 * .call audit_stats().
442 * .arg none.
443 * .ret void.
444 */
445 void
446 audit_stats(void)
447 {
448 struct rlimit rl;
449
450 if (getrlimit(RLIMIT_NOFILE, &rl) != -1)
451 (void) fprintf(stderr,
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright 2019 Joyent, Inc.
29 */
30
31 /*
32 * The Secure SunOS audit reduction tool - auditreduce.
33 * Document SM0071 is the primary source of information on auditreduce.
34 *
35 * Composed of 4 source modules:
36 * main.c - main driver.
37 * option.c - command line option processing.
38 * process.c - record/file/process functions.
39 * time.c - date/time handling.
40 *
41 * Main(), write_header(), audit_stats(), and a_calloc()
42 * are the only functions visible outside this module.
43 */
44
45 #include <siginfo.h>
46 #include <locale.h>
47 #include <libintl.h>
48 #include "auditr.h"
49 #include "auditrd.h"
50
51 #if !defined(TEXT_DOMAIN)
234 a_calloc(tofork, sizeof (*pcb));
235 nnsp = nsp / tofork; /* # of pcbs per forked process */
236 nrem = nsp % tofork; /* remainder to spread around */
237 /*
238 * Loop to fork all of the subs. Open a pipe for each.
239 * If there are any errors in pipes, forks, or getting streams
240 * for the pipes then quit altogether.
241 */
242 for (i = 0; i < tofork; i++) {
243 pcbn = &pcb->pcb_below[i];
244 pcbn->pcb_time = -1;
245 if (pipe(fildes)) {
246 perror(gettext(
247 "auditreduce: couldn't get a pipe"));
248 return (-1);
249 }
250 /*
251 * Convert descriptors to streams.
252 */
253 if ((pcbn->pcb_fpr = fdopen(fildes[0], "r")) == NULL) {
254 perror(gettext("auditreduce: couldn't get read "
255 "stream for pipe"));
256 return (-1);
257 }
258 if ((pcbn->pcb_fpw = fdopen(fildes[1], "w")) == NULL) {
259 perror(gettext("auditreduce: couldn't get "
260 "write stream for pipe"));
261 return (-1);
262 }
263 if ((procno = fork()) == -1) {
264 perror(gettext("auditreduce: fork failed"));
265 return (-1);
266 }
267 /*
268 * Calculate the range of pcbs from audit_pcbs [] this
269 * branch of the tree will be responsible for.
270 */
271 range = (nrem > 0) ? nnsp + 1 : nnsp;
272 /*
273 * Child route.
274 */
275 if (procno == 0) {
276 pcbn->pcb_procno = getpid();
277 c_close(pcb, i); /* close unused streams */
278 /*
279 * Continue resolving this branch.
280 */
389 * It also closes the read streams for the other children that
390 * have been born before it. If any closes fail a warning message
391 * is printed, but processing continues.
392 * .call ret = c_close(pcb, i).
393 * .arg pcb - ptr to the child's parent pcb.
394 * .arg i - iteration # of child in forking loop.
395 * .ret void.
396 */
397 static void
398 c_close(audit_pcb_t *pcb, int i)
399 {
400 int j;
401 audit_pcb_t *pcbt;
402
403 /*
404 * Do all pcbs in parent's group up to and including us
405 */
406 for (j = 0; j <= i; j++) {
407 pcbt = &pcb->pcb_below[j];
408 if (fclose(pcbt->pcb_fpr) == EOF) {
409 if (!f_quiet) {
410 perror(gettext("auditreduce: initial close "
411 "on pipe failed"));
412 }
413 }
414 /*
415 * Free the buffer allocated to hold incoming records.
416 */
417 if (i != j) {
418 free(pcbt->pcb_rec);
419 }
420 }
421 }
422
423
424 /*
425 * .func p_close - close unused streams for parent.
426 * .desc Called by the parent right after forking a child.
427 * Closes the write stream on the pipe to the child since
428 * we will never use it.
429 * .call p_close(pcbn),
430 * .arg pcbn - ptr to pcb.
431 * .ret void.
432 */
433 static void
434 p_close(audit_pcb_t *pcbn)
435 {
436 if (fclose(pcbn->pcb_fpw) == EOF) {
437 if (!f_quiet) {
438 perror(gettext("auditreduce: close for write "
439 "pipe failed"));
440 }
441 }
442 }
443
444
445 /*
446 * .func audit_stats - print statistics.
447 * .desc Print usage statistics for the user if the run fails.
448 * Tells them how many files they had and how many groups this
449 * totalled. Also tell them how many layers and processes the
450 * process tree had.
451 * .call audit_stats().
452 * .arg none.
453 * .ret void.
454 */
455 void
456 audit_stats(void)
457 {
458 struct rlimit rl;
459
460 if (getrlimit(RLIMIT_NOFILE, &rl) != -1)
461 (void) fprintf(stderr,
|