Print this page
12288 getfacl and setfacl could stand improvement

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/setfacl/setfacl.c
          +++ new/usr/src/cmd/setfacl/setfacl.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2020 Peter Tribble.
  23   24   */
  24   25  
  25   26  /*
  26   27   * setfacl [-r] -f aclfile file ...
  27   28   * setfacl [-r] -d acl_entries file ...
  28   29   * setfacl [-r] -m acl_entries file ...
  29   30   * setfacl [-r] -s acl_entries file ...
  30   31   * This command deletes/adds/modifies/sets discretionary information for a file
  31   32   * or files.
  32   33   */
↓ open down ↓ 1 lines elided ↑ open up ↑
  34   35  #include <stdlib.h>
  35   36  #include <stdio.h>
  36   37  #include <pwd.h>
  37   38  #include <grp.h>
  38   39  #include <string.h>
  39   40  #include <locale.h>
  40   41  #include <sys/acl.h>
  41   42  #include <sys/types.h>
  42   43  #include <unistd.h>
  43   44  #include <errno.h>
       45 +#include <ctype.h>
  44   46  
  45   47  #define ADD     1
  46   48  #define MODIFY  2
  47   49  #define DELETE  3
  48   50  #define SET     4
  49   51  
  50   52  static int get_acl_info(char *filep, aclent_t **aclpp);
  51   53  static int mod_entries(aclent_t *, int, char *, char *, char *, int);
  52   54  static int set_file_entries(char *, char *, int);
  53   55  static int set_online_entries(char *, char *, int);
↓ open down ↓ 9 lines elided ↑ open up ↑
  63   65  {
  64   66          int             c;
  65   67          int             dflag = 0;
  66   68          int             mflag = 0;
  67   69          int             rflag = 0;
  68   70          int             sflag = 0;
  69   71          int             fflag = 0;
  70   72          int             errflag = 0;
  71   73          int             aclcnt;                 /* used by -m -d */
  72   74          aclent_t        *aclp;                  /* used by -m -d */
  73      -        char            *aclfilep;              /* acl file argument */
       75 +        char            *aclfilep = NULL;               /* acl file argument */
  74   76          char            *d_entryp = NULL;       /* ptr to del entry list */
  75   77          char            *m_entryp = NULL;       /* ptr to mod entry list */
  76   78          char            *s_entryp = NULL;       /* ptr to set entry list */
  77   79          char            *work_dp = NULL;        /* working ptrs for the above */
  78   80          char            *work_mp = NULL;
  79   81          char            *work_sp = NULL;
  80   82  
  81   83          (void) setlocale(LC_ALL, "");
  82   84          (void) textdomain(TEXT_DOMAIN);
  83   85  
↓ open down ↓ 108 lines elided ↑ open up ↑
 192  194  get_acl_info(char *filep, aclent_t **aclpp)
 193  195  {
 194  196          int     aclcnt;
 195  197  
 196  198          if ((aclcnt = acl(filep, GETACLCNT, 0, NULL)) < 0) {
 197  199                  if (errno == ENOSYS) {
 198  200                          (void) fprintf(stderr,
 199  201                              gettext("File system doesn't support aclent_t "
 200  202                              "style ACL's.\n"
 201  203                              "See acl(5) for more information on"
 202      -                            " ACL styles support by Solaris.\n"));
      204 +                            "POSIX-draft ACL support.\n"));
 203  205                          return (-1);
 204  206                  }
 205  207                  (void) fprintf(stderr,
 206  208                      gettext("%s: failed to get acl count\n"), filep);
 207  209                  perror("get acl count error");
 208  210                  return (-1);
 209  211          }
 210  212          if (aclcnt < MIN_ACL_ENTRIES) {
 211  213                  (void) fprintf(stderr,
 212  214                      gettext("%d: acl count is too small from %s\n"),
↓ open down ↓ 17 lines elided ↑ open up ↑
 230  232  /*
 231  233   * mod_entries() handles add, delete, and modify ACL entries of a file.
 232  234   * The real action is in convert_to_aclent_t() called by parse_entry_list().
 233  235   * aclp: points ACL of a file and may be changed by lower level routine.
 234  236   * modp: modify entry list in ascii format
 235  237   * delp: delete entry list in ascii format
 236  238   * fnamep: file of interest
 237  239   */
 238  240  static int
 239  241  mod_entries(aclent_t *aclp, int cnt, char *modp, char *delp,
 240      -        char *fnamep, int rfg)
      242 +    char *fnamep, int rfg)
 241  243  {
 242      -        int     rc;             /* return code */
 243      -
 244  244          /* modify and add: from -m option */
 245  245          if (parse_entry_list(&aclp, &cnt, modp, MODIFY) == -1)
 246  246                  return (-1);
 247  247  
 248  248          /* deletion: from -d option */
 249  249          if (parse_entry_list(&aclp, &cnt, delp, DELETE) == -1)
 250  250                  return (-1);
 251  251  
 252  252          if (aclsort(cnt, rfg, aclp) == -1) {
 253  253                  (void) err_handle(cnt, aclp);
↓ open down ↓ 81 lines elided ↑ open up ↑
 335  335  
 336  336  /*
 337  337   * set_online_entries() parses the acl entries from command line (setp).
 338  338   * It converts the comma separated acl entries into aclent_t format.
 339  339   * It then recalculates the mask according to rflag.
 340  340   * Finally it sets ACL to the file (fnamep).
 341  341   */
 342  342  static int
 343  343  set_online_entries(char *setp, char *fnamep, int rflag)
 344  344  {
 345      -        char            *commap;
 346  345          aclent_t        *aclp;
 347  346          int             aclcnt = 0;
 348  347  
 349  348          if (parse_entry_list(&aclp, &aclcnt, setp, SET) == -1)
 350  349                  return (-1);
 351  350  
 352  351          if (aclsort(aclcnt, rflag, aclp) == -1) {
 353  352                  (void) err_handle(aclcnt, aclp);
 354  353                  (void) fprintf(stderr,
 355  354                      gettext("aclcnt %d, file %s\n"), aclcnt, fnamep);
↓ open down ↓ 51 lines elided ↑ open up ↑
 407  406          aclent_t        *new_aclp;
 408  407          aclent_t        tmpacl;
 409  408          aclent_t        *taclp, *centry = NULL, *gentry = NULL;
 410  409          int             cur_cnt;
 411  410          int             found = 0;
 412  411          int             is_obj;
 413  412  
 414  413          if (entryp == NULL)
 415  414                  return (0);
 416  415  
 417      -        if (*cntp > 1)
 418      -                new_aclp = (aclent_t *)realloc(*aclpp,
 419      -                    sizeof (aclent_t) * (*cntp));
 420      -        else
 421      -                new_aclp = (aclent_t *) malloc(sizeof (aclent_t) * (*cntp));
 422      -        if (new_aclp == NULL) {
 423      -                fprintf(stderr,
 424      -                    gettext("Insufficient memory for acl %d\n"), *cntp);
 425      -                return (-1);
 426      -        }
 427      -
 428  416          tmpacl.a_id = 0;        /* id field needs to be initialized */
 429  417          if (entryp[0] == 'u')
 430  418                  tmpacl.a_id = getuid(); /* id field for user */
 431  419          if (entryp[0] == 'g')
 432  420                  tmpacl.a_id = getgid(); /* id field for group */
 433  421  
 434  422          tmpacl.a_type = 0;
 435  423          if (parse_entry(entryp, &tmpacl, mode) == -1)
 436  424                  return (-1);
 437  425  
 438  426          is_obj = ((tmpacl.a_type == USER_OBJ) ||
 439  427              (tmpacl.a_type == GROUP_OBJ) ||
 440  428              (tmpacl.a_type == CLASS_OBJ) ||
 441  429              (tmpacl.a_type == DEF_USER_OBJ) ||
 442  430              (tmpacl.a_type == DEF_GROUP_OBJ) ||
 443  431              (tmpacl.a_type == DEF_OTHER_OBJ));
 444  432  
      433 +        if (*cntp > 1)
      434 +                new_aclp = (aclent_t *)realloc(*aclpp,
      435 +                    sizeof (aclent_t) * (*cntp));
      436 +        else
      437 +                new_aclp = (aclent_t *) malloc(sizeof (aclent_t) * (*cntp));
      438 +        if (new_aclp == NULL) {
      439 +                fprintf(stderr,
      440 +                    gettext("Insufficient memory for acl %d\n"), *cntp);
      441 +                return (-1);
      442 +        }
      443 +
 445  444          cur_cnt = *cntp - 1;
 446  445          switch (mode) {
 447  446          case MODIFY:    /* and add */
 448  447                  for (taclp = new_aclp; cur_cnt-- > 0; taclp++) {
 449  448                          if (taclp->a_type == tmpacl.a_type &&
 450  449                              ((taclp->a_id == tmpacl.a_id) || is_obj)) {
 451  450                                  found++;
 452  451                                  /* cnt is added before it's called */
 453  452                                  *cntp -= 1;
 454  453                                  taclp->a_perm = tmpacl.a_perm;
↓ open down ↓ 58 lines elided ↑ open up ↑
 513  512                                           * Confirmed that the new acl set is
 514  513                                           * still a non-trivial acl.
 515  514                                           * Skip reset.
 516  515                                           */
 517  516                                          trivial = B_FALSE;
 518  517                          }
 519  518                  }
 520  519                  if (centry != NULL && gentry != NULL && trivial == B_TRUE)
 521  520                          centry->a_perm = gentry->a_perm;
 522  521          }
 523      -        *aclpp = new_aclp;      /* return new acl entries */
      522 +        *aclpp = new_aclp;      /* return new acl entries */
 524  523          return (0);
 525  524  }
 526  525  
 527  526  static void
 528  527  usage()
 529  528  {
 530  529          (void) fprintf(stderr, gettext("usage:\n"));
 531  530          (void) fprintf(stderr,
 532  531              gettext("\tsetfacl [-r] -f aclfile file ...\n"));
 533  532          (void) fprintf(stderr,
↓ open down ↓ 296 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX