8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / ptools / psecflags / psecflags.c
blobb26139b88ce402335e9267910b808b4314ffc271
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
12 /* Copyright 2015, Richard Lowe. */
14 #include <err.h>
15 #include <errno.h>
16 #include <grp.h>
17 #include <libintl.h>
18 #include <procfs.h>
19 #include <project.h>
20 #include <pwd.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/secflags.h>
25 #include <sys/types.h>
27 #include <libproc.h>
28 #include <libzonecfg.h>
30 extern const char *__progname;
32 static void
33 print_flags(const char *set, secflagset_t flags)
35 char buf[1024];
37 secflags_to_str(flags, buf, sizeof (buf));
38 (void) printf("\t%s:\t%s\n", set, buf);
42 * Structure defining idtypes known to the priocntl command
43 * along with the corresponding names.
44 * The idtype values themselves are defined in <sys/procset.h>.
46 static struct idtypes {
47 idtype_t type;
48 char *name;
49 } idtypes [] = {
50 { P_ALL, "all" },
51 { P_CTID, "contract" },
52 { P_CTID, "ctid" },
53 { P_GID, "gid" },
54 { P_GID, "group" },
55 { P_PGID, "pgid" },
56 { P_PID, "pid" },
57 { P_PPID, "ppid" },
58 { P_PROJID, "project" },
59 { P_PROJID, "projid" },
60 { P_SID, "session", },
61 { P_SID, "sid" },
62 { P_SID, "sid" },
63 { P_TASKID, "taskid" },
64 { P_UID, "uid" },
65 { P_UID, "user" },
66 { P_ZONEID, "zone" },
67 { P_ZONEID, "zoneid" },
68 { 0, NULL }
71 static int
72 str2idtype(char *idtypnm, idtype_t *idtypep)
74 struct idtypes *curp;
76 for (curp = idtypes; curp->name != NULL; curp++) {
77 if (strncasecmp(curp->name, idtypnm,
78 strlen(curp->name)) == 0) {
79 *idtypep = curp->type;
80 return (0);
83 return (-1);
86 static id_t
87 getid(idtype_t type, char *value)
89 struct passwd *pwd;
90 struct group *grp;
91 id_t ret;
92 char *endp;
94 switch (type) {
95 case P_UID:
96 if ((pwd = getpwnam(value)) != NULL)
97 return (pwd->pw_uid);
98 break;
99 case P_GID:
100 if ((grp = getgrnam(value)) != NULL)
101 return (grp->gr_gid);
102 break;
103 case P_PROJID:
104 if ((ret = getprojidbyname(value)) != (id_t)-1)
105 return (ret);
106 break;
107 case P_ZONEID:
108 if (zone_get_id(value, &ret) == 0)
109 return (ret);
110 break;
111 default:
112 break;
115 errno = 0;
117 ret = (id_t)strtoul(value, &endp, 10);
119 if ((errno != 0) || (*endp != '\0'))
120 return ((id_t)-1);
122 return (ret);
126 main(int argc, char **argv)
128 secflagdelta_t act;
129 psecflagwhich_t which = PSF_INHERIT;
130 int ret = 0;
131 int pgrab_flags = PGRAB_RDONLY;
132 int opt;
133 char *idtypename = NULL;
134 idtype_t idtype = P_PID;
135 boolean_t usage = B_FALSE;
136 boolean_t e_flag = B_FALSE;
137 boolean_t l_flag = B_FALSE;
138 boolean_t s_flag = B_FALSE;
139 int errc = 0;
141 while ((opt = getopt(argc, argv, "eFi:ls:")) != -1) {
142 switch (opt) {
143 case 'e':
144 e_flag = B_TRUE;
145 break;
146 case 'F':
147 pgrab_flags |= PGRAB_FORCE;
148 break;
149 case 'i':
150 idtypename = optarg;
151 break;
152 case 's':
153 s_flag = B_TRUE;
154 if ((strlen(optarg) >= 2) &&
155 ((optarg[1] == '='))) {
156 switch (optarg[0]) {
157 case 'L':
158 which = PSF_LOWER;
159 break;
160 case 'U':
161 which = PSF_UPPER;
162 break;
163 case 'I':
164 which = PSF_INHERIT;
165 break;
166 case 'E':
167 errx(1, "the effective flags cannot "
168 "be changed", optarg[0]);
169 default:
170 errx(1, "unknown security flag "
171 "set: '%c'", optarg[0]);
174 optarg += 2;
177 if (secflags_parse(NULL, optarg, &act) == -1)
178 errx(1, "couldn't parse security flags: %s",
179 optarg);
180 break;
181 case 'l':
182 l_flag = B_TRUE;
183 break;
184 default:
185 usage = B_TRUE;
186 break;
190 argc -= optind;
191 argv += optind;
193 if (l_flag && ((idtypename != NULL) || s_flag || (argc != 0)))
194 usage = B_TRUE;
195 if ((idtypename != NULL) && !s_flag)
196 usage = B_TRUE;
197 if (e_flag && !s_flag)
198 usage = B_TRUE;
199 if (!l_flag && argc <= 0)
200 usage = B_TRUE;
202 if (usage) {
203 (void) fprintf(stderr,
204 gettext("usage:\t%s [-F] { pid | core } ...\n"),
205 __progname);
206 (void) fprintf(stderr,
207 gettext("\t%s -s spec [-i idtype] id ...\n"),
208 __progname);
209 (void) fprintf(stderr,
210 gettext("\t%s -s spec -e command [arg]...\n"),
211 __progname);
212 (void) fprintf(stderr, gettext("\t%s -l\n"), __progname);
213 return (2);
216 if (l_flag) {
217 secflag_t i;
218 const char *name;
220 for (i = 0; (name = secflag_to_str(i)) != NULL; i++)
221 (void) printf("%s\n", name);
222 return (0);
223 } else if (s_flag && e_flag) {
225 * Don't use the strerror() message for EPERM, "Not Owner"
226 * which is misleading.
228 errc = psecflags(P_PID, P_MYID, which, &act);
229 switch (errc) {
230 case 0:
231 break;
232 case EPERM:
233 errx(1, gettext("failed setting "
234 "security-flags: Permission denied"));
235 break;
236 default:
237 err(1, gettext("failed setting security-flags"));
240 (void) execvp(argv[0], &argv[0]);
241 err(1, "%s", argv[0]);
242 } else if (s_flag) {
243 int i;
244 id_t id;
246 if (idtypename != NULL)
247 if (str2idtype(idtypename, &idtype) == -1)
248 errx(1, gettext("No such id type: '%s'"),
249 idtypename);
251 for (i = 0; i < argc; i++) {
252 if ((id = getid(idtype, argv[i])) == (id_t)-1) {
253 errx(1, gettext("invalid or non-existent "
254 "identifier: '%s'"), argv[i]);
258 * Don't use the strerror() message for EPERM, "Not
259 * Owner" which is misleading.
261 if (psecflags(idtype, id, which, &act) != 0) {
262 switch (errno) {
263 case EPERM:
264 errx(1, gettext("failed setting "
265 "security-flags: "
266 "Permission denied"));
267 break;
268 default:
269 err(1, gettext("failed setting "
270 "security-flags"));
275 return (0);
278 /* Display the flags for the given pids */
279 while (argc-- > 0) {
280 struct ps_prochandle *Pr;
281 const char *arg;
282 psinfo_t psinfo;
283 prsecflags_t *psf;
284 int gcode;
286 if ((Pr = proc_arg_grab(arg = *argv++, PR_ARG_ANY,
287 pgrab_flags, &gcode)) == NULL) {
288 warnx(gettext("cannot examine %s: %s"),
289 arg, Pgrab_error(gcode));
290 ret = 1;
291 continue;
294 (void) memcpy(&psinfo, Ppsinfo(Pr), sizeof (psinfo_t));
295 proc_unctrl_psinfo(&psinfo);
297 if (Pstate(Pr) == PS_DEAD) {
298 (void) printf(gettext("core '%s' of %d:\t%.70s\n"),
299 arg, (int)psinfo.pr_pid, psinfo.pr_psargs);
300 } else {
301 (void) printf("%d:\t%.70s\n",
302 (int)psinfo.pr_pid, psinfo.pr_psargs);
305 if (Psecflags(Pr, &psf) != 0)
306 err(1, gettext("cannot read secflags of %s"), arg);
308 print_flags("E", psf->pr_effective);
309 print_flags("I", psf->pr_inherit);
310 print_flags("L", psf->pr_lower);
311 print_flags("U", psf->pr_upper);
313 Psecflags_free(psf);
314 Prelease(Pr, 0);
317 return (ret);