Print this page
new smatch


   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,