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