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.
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.
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]
22 * Copyright 2014 Gary Mills
23 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
27 * New implementation of pfexec(1) and all of the profile shells.
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
34 * argv[0] is also our fallback in case getexecname doesn't find it.
36 #include <sys/param.h>
46 #define PFEXEC "pfexec"
48 #define TEXT_DOMAIN "SYS_TEST"
53 #define RES_FAILURE -1
56 * Return the shellname
59 shellname(const char *name
, char buf
[MAXPATHLEN
])
61 const char *cmd
= strrchr(name
, '/');
68 if (strncmp(cmd
, "pf", 2) != 0)
71 if (strcmp(cmd
, PFEXEC
) == 0)
74 if (strlen(name
) >= MAXPATHLEN
)
78 (void) strlcpy(buf
, cmd
+ 2, MAXPATHLEN
);
80 (void) strncpy(buf
, name
, cmd
- name
);
81 (void) strcpy(buf
+ (cmd
- name
), cmd
+ 2);
90 (void) fprintf(stderr
, gettext("pfexec [-P privset] cmd [arg ..]\n"));
95 main(int argc
, char **argv
)
99 char pathbuf
[MAXPATHLEN
];
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"),
117 /* Strip "pf" from argv[0], it confuses some shells. */
118 if (strncmp(cmd
, "pf", 2) == 0) {
120 /* argv[0] will need to start with '-' again. */
121 if (argv
[0][-2] == '-')
125 /* If this fails, we just continue with plan B */
126 if (shellname(getexecname(), pathbuf
) == RES_OK
)
127 (void) execv(pathbuf
, argv
);
129 switch (shellname(cmd
, pathbuf
)) {
131 (void) execv(pathbuf
, argv
);
132 (void) fprintf(stderr
,
133 gettext("pfexec: unable to execute %s: %s\n"),
134 pathbuf
, strerror(errno
));
138 while ((c
= getopt(argc
, argv
, "P:")) != EOF
) {
156 if ((wanted
= priv_str_to_set(pset
, ",", NULL
)) ==
158 (void) fprintf(stderr
,
159 gettext("pfexec: error parsing "
160 "privileges: %s\n"), strerror(errno
));
163 if (setppriv(PRIV_ON
, PRIV_INHERITABLE
, wanted
) != 0) {
164 (void) fprintf(stderr
,
165 gettext("pfexec: error setting "
166 "privileges: %s\n"), strerror(errno
));
169 (void) setpflags(PRIV_PFEXEC
, oflag
);
172 (void) execvp(argv
[0], argv
);
173 (void) fprintf(stderr
,
174 gettext("pfexec: unable to execute %s: %s\n"),
175 argv
[0], strerror(errno
));