2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /*
26 * New implementation of pfexec(1) and all of the profile shells.
27 *
28 * The algorithm is as follows:
29 * first try to derive the shell's path from getexecname();
30 * note that this requires a *hard* link to the program, so
31 * if we find that we are actually executing pfexec, we start
32 * looking at argv[0].
33 * argv[0] is also our fallback in case getexecname doesn't find it.
34 */
35 #include <sys/param.h>
36 #include <alloca.h>
37 #include <errno.h>
38 #include <locale.h>
39 #include <priv.h>
40 #include <stdio.h>
41 #include <stdlib.h>
85
86 static void
87 usage(void)
88 {
89 (void) fprintf(stderr, gettext("pfexec [-P privset] cmd [arg ..]\n"));
90 exit(EXIT_FAILURE);
91 }
92
93 int
94 main(int argc, char **argv)
95 {
96 char *cmd;
97 char *pset = NULL;
98 char pathbuf[MAXPATHLEN];
99 int c;
100 priv_set_t *wanted;
101 int oflag;
102
103 oflag = getpflags(PRIV_PFEXEC);
104 if (setpflags(PRIV_PFEXEC, 1) != 0) {
105 perror("setpflags(PRIV_PFEXEC)");
106 exit(1);
107 }
108
109 if (*argv[0] == '-')
110 cmd = argv[0] + 1;
111 else
112 cmd = argv[0];
113
114 /* Strip "pf" from argv[0], it confuses some shells. */
115 if (strncmp(cmd, "pf", 2) == 0) {
116 argv[0] += 2;
117 /* argv[0] will need to start with '-' again. */
118 if (argv[0][-2] == '-')
119 *argv[0] = '-';
120 }
121
122 /* If this fails, we just continue with plan B */
123 if (shellname(getexecname(), pathbuf) == RES_OK)
124 (void) execv(pathbuf, argv);
125
126 switch (shellname(cmd, pathbuf)) {
127 case RES_OK:
128 (void) execv(pathbuf, argv);
129 perror(pathbuf);
130 return (1);
131 case RES_PFEXEC:
132 case RES_FAILURE:
133 while ((c = getopt(argc, argv, "P:")) != EOF) {
134 switch (c) {
135 case 'P':
136 if (pset == NULL) {
137 pset = optarg;
138 break;
139 }
140 /* FALLTHROUGH */
141 default:
142 usage();
143 }
144 }
145 argc -= optind;
146 argv += optind;
147 if (argc < 1)
148 usage();
149
150 if (pset != NULL) {
151 wanted = priv_str_to_set(pset, ",", NULL);
152 if (setppriv(PRIV_ON, PRIV_INHERITABLE, wanted) != 0) {
153 (void) fprintf(stderr,
154 gettext("setppriv(): %s\n"),
155 strerror(errno));
156 exit(EXIT_FAILURE);
157 }
158 (void) setpflags(PRIV_PFEXEC, oflag);
159 }
160
161 (void) execvp(argv[0], argv);
162 perror(argv[0]);
163 return (1);
164 }
165 return (1);
166 }
|
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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 * Copyright 2014 Gary Mills
23 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /*
27 * New implementation of pfexec(1) and all of the profile shells.
28 *
29 * The algorithm is as follows:
30 * first try to derive the shell's path from getexecname();
31 * note that this requires a *hard* link to the program, so
32 * if we find that we are actually executing pfexec, we start
33 * looking at argv[0].
34 * argv[0] is also our fallback in case getexecname doesn't find it.
35 */
36 #include <sys/param.h>
37 #include <alloca.h>
38 #include <errno.h>
39 #include <locale.h>
40 #include <priv.h>
41 #include <stdio.h>
42 #include <stdlib.h>
86
87 static void
88 usage(void)
89 {
90 (void) fprintf(stderr, gettext("pfexec [-P privset] cmd [arg ..]\n"));
91 exit(EXIT_FAILURE);
92 }
93
94 int
95 main(int argc, char **argv)
96 {
97 char *cmd;
98 char *pset = NULL;
99 char pathbuf[MAXPATHLEN];
100 int c;
101 priv_set_t *wanted;
102 int oflag;
103
104 oflag = getpflags(PRIV_PFEXEC);
105 if (setpflags(PRIV_PFEXEC, 1) != 0) {
106 (void) fprintf(stderr,
107 gettext("pfexec: unable to set PFEXEC flag: %s\n"),
108 strerror(errno));
109 exit(1);
110 }
111
112 if (*argv[0] == '-')
113 cmd = argv[0] + 1;
114 else
115 cmd = argv[0];
116
117 /* Strip "pf" from argv[0], it confuses some shells. */
118 if (strncmp(cmd, "pf", 2) == 0) {
119 argv[0] += 2;
120 /* argv[0] will need to start with '-' again. */
121 if (argv[0][-2] == '-')
122 *argv[0] = '-';
123 }
124
125 /* If this fails, we just continue with plan B */
126 if (shellname(getexecname(), pathbuf) == RES_OK)
127 (void) execv(pathbuf, argv);
128
129 switch (shellname(cmd, pathbuf)) {
130 case RES_OK:
131 (void) execv(pathbuf, argv);
132 (void) fprintf(stderr,
133 gettext("pfexec: unable to execute %s: %s\n"),
134 pathbuf, strerror(errno));
135 return (1);
136 case RES_PFEXEC:
137 case RES_FAILURE:
138 while ((c = getopt(argc, argv, "P:")) != EOF) {
139 switch (c) {
140 case 'P':
141 if (pset == NULL) {
142 pset = optarg;
143 break;
144 }
145 /* FALLTHROUGH */
146 default:
147 usage();
148 }
149 }
150 argc -= optind;
151 argv += optind;
152 if (argc < 1)
153 usage();
154
155 if (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 }
163 if (setppriv(PRIV_ON, PRIV_INHERITABLE, wanted) != 0) {
164 (void) fprintf(stderr,
165 gettext("pfexec: error setting "
166 "privileges: %s\n"), strerror(errno));
167 exit(EXIT_FAILURE);
168 }
169 (void) setpflags(PRIV_PFEXEC, oflag);
170 }
171
172 (void) execvp(argv[0], argv);
173 (void) fprintf(stderr,
174 gettext("pfexec: unable to execute %s: %s\n"),
175 argv[0], strerror(errno));
176 return (1);
177 }
178 return (1);
179 }
|