Print this page
    
4577 pfexec's error reporting is (at least sometimes) awful
    
      
        | Split | Close | 
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/pfexec/pfexec.c
          +++ new/usr/src/cmd/pfexec/pfexec.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  
    | ↓ open down ↓ | 11 lines elided | ↑ open up ↑ | 
  12   12   *
  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 + * Copyright 2014 Gary Mills
  22   23   * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  23   24   */
  24   25  
  25   26  /*
  26   27   * New implementation of pfexec(1) and all of the profile shells.
  27   28   *
  28   29   * The algorithm is as follows:
  29   30   *      first try to derive the shell's path from getexecname();
  30   31   *      note that this requires a *hard* link to the program, so
  31   32   *      if we find that we are actually executing pfexec, we start
  32   33   *      looking at argv[0].
  33   34   *      argv[0] is also our fallback in case getexecname doesn't find it.
  34   35   */
  35   36  #include <sys/param.h>
  36   37  #include <alloca.h>
  37   38  #include <errno.h>
  38   39  #include <locale.h>
  39   40  #include <priv.h>
  40   41  #include <stdio.h>
  41   42  #include <stdlib.h>
  42   43  #include <string.h>
  43   44  #include <unistd.h>
  44   45  
  45   46  #define PFEXEC  "pfexec"
  46   47  #ifndef TEXT_DOMAIN
  47   48  #define TEXT_DOMAIN     "SYS_TEST"
  48   49  #endif
  49   50  
  50   51  #define RES_PFEXEC      1
  51   52  #define RES_OK          0
  52   53  #define RES_FAILURE     -1
  53   54  
  54   55  /*
  55   56   * Return the shellname
  56   57   */
  57   58  int
  58   59  shellname(const char *name, char buf[MAXPATHLEN])
  59   60  {
  60   61          const char *cmd = strrchr(name, '/');
  61   62  
  62   63          if (cmd == NULL)
  63   64                  cmd = name;
  64   65          else
  65   66                  cmd++;
  66   67  
  67   68          if (strncmp(cmd, "pf", 2) != 0)
  68   69                  return (RES_FAILURE);
  69   70  
  70   71          if (strcmp(cmd, PFEXEC) == 0)
  71   72                  return (RES_PFEXEC);
  72   73  
  73   74          if (strlen(name) >= MAXPATHLEN)
  74   75                  return (RES_FAILURE);
  75   76  
  76   77          if (cmd == name) {
  77   78                  (void) strlcpy(buf, cmd + 2, MAXPATHLEN);
  78   79          } else {
  79   80                  (void) strncpy(buf, name, cmd - name);
  80   81                  (void) strcpy(buf + (cmd - name), cmd + 2);
  81   82          }
  82   83          return (RES_OK);
  83   84  
  84   85  }
  85   86  
  86   87  static void
  87   88  usage(void)
  88   89  {
  89   90          (void) fprintf(stderr, gettext("pfexec [-P privset] cmd [arg ..]\n"));
  90   91          exit(EXIT_FAILURE);
  91   92  }
  92   93  
  93   94  int
  94   95  main(int argc, char **argv)
  
    | ↓ open down ↓ | 63 lines elided | ↑ open up ↑ | 
  95   96  {
  96   97          char *cmd;
  97   98          char *pset = NULL;
  98   99          char pathbuf[MAXPATHLEN];
  99  100          int c;
 100  101          priv_set_t *wanted;
 101  102          int oflag;
 102  103  
 103  104          oflag = getpflags(PRIV_PFEXEC);
 104  105          if (setpflags(PRIV_PFEXEC, 1) != 0) {
 105      -                perror("setpflags(PRIV_PFEXEC)");
      106 +                (void) fprintf(stderr,
      107 +                    gettext("pfexec: unable to set PFEXEC flag: %s\n"),
      108 +                    strerror(errno));
 106  109                  exit(1);
 107  110          }
 108  111  
 109  112          if (*argv[0] == '-')
 110  113                  cmd = argv[0] + 1;
 111  114          else
 112  115                  cmd = argv[0];
 113  116  
 114  117          /* Strip "pf" from argv[0], it confuses some shells. */
 115  118          if (strncmp(cmd, "pf", 2) == 0) {
 116  119                  argv[0] += 2;
 117  120                  /* argv[0] will need to start with '-' again. */
 118  121                  if (argv[0][-2] == '-')
  
    | ↓ open down ↓ | 3 lines elided | ↑ open up ↑ | 
 119  122                          *argv[0] = '-';
 120  123          }
 121  124  
 122  125          /* If this fails, we just continue with plan B */
 123  126          if (shellname(getexecname(), pathbuf) == RES_OK)
 124  127                  (void) execv(pathbuf, argv);
 125  128  
 126  129          switch (shellname(cmd, pathbuf)) {
 127  130          case RES_OK:
 128  131                  (void) execv(pathbuf, argv);
 129      -                perror(pathbuf);
      132 +                (void) fprintf(stderr,
      133 +                    gettext("pfexec: unable to execute %s: %s\n"),
      134 +                    pathbuf, strerror(errno));
 130  135                  return (1);
 131  136          case RES_PFEXEC:
 132  137          case RES_FAILURE:
 133  138                  while ((c = getopt(argc, argv, "P:")) != EOF) {
 134  139                          switch (c) {
 135  140                          case 'P':
 136  141                                  if (pset == NULL) {
 137  142                                          pset = optarg;
 138  143                                          break;
 139  144                                  }
 140  145                                  /* FALLTHROUGH */
  
    | ↓ open down ↓ | 1 lines elided | ↑ open up ↑ | 
 141  146                          default:
 142  147                                  usage();
 143  148                          }
 144  149                  }
 145  150                  argc -= optind;
 146  151                  argv += optind;
 147  152                  if (argc < 1)
 148  153                          usage();
 149  154  
 150  155                  if (pset != NULL) {
 151      -                        wanted = priv_str_to_set(pset, ",", NULL);
      156 +                        if ((wanted = priv_str_to_set(pset, ",", NULL)) ==
      157 +                            NULL) {
      158 +                                (void) fprintf(stderr,
      159 +                                    gettext("pfexec: error parsing "
      160 +                                    "privileges: %s\n"), strerror(errno));
      161 +                                exit(EXIT_FAILURE);
      162 +                        }
 152  163                          if (setppriv(PRIV_ON, PRIV_INHERITABLE, wanted) != 0) {
 153  164                                  (void) fprintf(stderr,
 154      -                                    gettext("setppriv(): %s\n"),
 155      -                                    strerror(errno));
      165 +                                    gettext("pfexec: error setting "
      166 +                                    "privileges: %s\n"), strerror(errno));
 156  167                                  exit(EXIT_FAILURE);
 157  168                          }
 158  169                          (void) setpflags(PRIV_PFEXEC, oflag);
 159  170                  }
 160  171  
 161  172                  (void) execvp(argv[0], argv);
 162      -                perror(argv[0]);
      173 +                (void) fprintf(stderr,
      174 +                    gettext("pfexec: unable to execute %s: %s\n"),
      175 +                    argv[0], strerror(errno));
 163  176                  return (1);
 164  177          }
 165  178          return (1);
 166  179  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX