Print this page
3946 ::gcore
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/ptools/ppriv/ppriv.c
+++ new/usr/src/cmd/ptools/ppriv/ppriv.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.
12 12 *
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
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 22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 - *
23 + */
24 +/*
25 + * Copyright (c) 2013 by Delphix. All rights reserved.
26 + */
27 +/*
24 28 * Program to examine or set process privileges.
25 29 */
26 30
27 31 #include <stdio.h>
28 32 #include <stdio_ext.h>
29 33 #include <stdlib.h>
30 34 #include <unistd.h>
31 35 #include <fcntl.h>
32 36 #include <string.h>
33 37 #include <limits.h>
34 38 #include <sys/types.h>
35 39 #include <libproc.h>
36 40 #include <priv.h>
37 41 #include <errno.h>
38 42 #include <ctype.h>
39 43
40 44 #include <locale.h>
41 45 #include <langinfo.h>
42 46
43 47 static int look(char *);
44 48 static void perr(char *);
45 49 static void usage(void);
46 50 static void loadprivinfo(void);
47 51 static int parsespec(const char *);
48 52 static void privupdate(prpriv_t *, const char *);
49 53 static void privupdate_self(void);
50 54 static int dumppriv(char **);
51 55 static void flags2str(uint_t);
52 56
53 57 static char *command;
54 58 static char *procname;
55 59 static boolean_t verb = B_FALSE;
56 60 static boolean_t set = B_FALSE;
57 61 static boolean_t exec = B_FALSE;
58 62 static boolean_t Don = B_FALSE;
59 63 static boolean_t Doff = B_FALSE;
60 64 static boolean_t list = B_FALSE;
61 65 static boolean_t mac_aware = B_FALSE;
62 66 static boolean_t pfexec = B_FALSE;
63 67 static boolean_t xpol = B_FALSE;
64 68 static int mode = PRIV_STR_PORT;
65 69
66 70 int
67 71 main(int argc, char **argv)
68 72 {
69 73 int rc = 0;
70 74 int opt;
71 75 struct rlimit rlim;
72 76
73 77 (void) setlocale(LC_ALL, "");
74 78 (void) textdomain(TEXT_DOMAIN);
75 79
76 80 if ((command = strrchr(argv[0], '/')) != NULL)
77 81 command++;
78 82 else
79 83 command = argv[0];
80 84
81 85 while ((opt = getopt(argc, argv, "lDMNPevs:xS")) != EOF) {
82 86 switch (opt) {
83 87 case 'l':
84 88 list = B_TRUE;
85 89 break;
86 90 case 'D':
87 91 set = B_TRUE;
88 92 Don = B_TRUE;
89 93 break;
90 94 case 'M':
91 95 mac_aware = B_TRUE;
92 96 break;
93 97 case 'N':
94 98 set = B_TRUE;
95 99 Doff = B_TRUE;
96 100 break;
97 101 case 'P':
98 102 set = B_TRUE;
99 103 pfexec = B_TRUE;
100 104 break;
101 105 case 'e':
102 106 exec = B_TRUE;
103 107 break;
104 108 case 'S':
105 109 mode = PRIV_STR_SHORT;
106 110 break;
107 111 case 'v':
108 112 verb = B_TRUE;
109 113 mode = PRIV_STR_LIT;
110 114 break;
111 115 case 's':
112 116 set = B_TRUE;
113 117 if ((rc = parsespec(optarg)) != 0)
114 118 return (rc);
115 119 break;
116 120 case 'x':
117 121 set = B_TRUE;
118 122 xpol = B_TRUE;
119 123 break;
120 124 default:
121 125 usage();
122 126 /*NOTREACHED*/
123 127 }
124 128 }
125 129
126 130 argc -= optind;
127 131 argv += optind;
128 132
129 133 if ((argc < 1 && !list) || Doff && Don || list && (set || exec) ||
130 134 (mac_aware && !exec))
131 135 usage();
132 136
133 137 /*
134 138 * Make sure we'll have enough file descriptors to handle a target
135 139 * that has many many mappings.
136 140 */
137 141 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
138 142 rlim.rlim_cur = rlim.rlim_max;
139 143 (void) setrlimit(RLIMIT_NOFILE, &rlim);
140 144 (void) enable_extended_FILE_stdio(-1, -1);
141 145 }
142 146
143 147 if (exec) {
144 148 privupdate_self();
145 149 rc = execvp(argv[0], &argv[0]);
146 150 (void) fprintf(stderr, "%s: %s: %s\n", command, argv[0],
147 151 strerror(errno));
148 152 } else if (list) {
149 153 rc = dumppriv(argv);
150 154 } else {
↓ open down ↓ |
117 lines elided |
↑ open up ↑ |
151 155 while (argc-- > 0)
152 156 rc += look(*argv++);
153 157 }
154 158
155 159 return (rc);
156 160 }
157 161
158 162 static int
159 163 look(char *arg)
160 164 {
161 - static size_t pprivsz = sizeof (prpriv_t);
162 - static prpriv_t *ppriv;
163 -
164 165 struct ps_prochandle *Pr;
165 166 int gcode;
166 167 size_t sz;
167 168 void *pdata;
168 169 char *x;
169 170 int i;
170 171 boolean_t nodata;
172 + prpriv_t *ppriv;
171 173
172 174 procname = arg; /* for perr() */
173 175
174 176 if ((Pr = proc_arg_grab(arg, set ? PR_ARG_PIDS : PR_ARG_ANY,
175 177 PGRAB_RETAIN | PGRAB_FORCE | (set ? 0 : PGRAB_RDONLY) |
176 178 PGRAB_NOSTOP, &gcode)) == NULL) {
177 179 (void) fprintf(stderr, "%s: cannot examine %s: %s\n",
178 180 command, arg, Pgrab_error(gcode));
179 181 return (1);
180 182 }
181 183
182 - if (ppriv == NULL)
183 - ppriv = malloc(pprivsz);
184 -
185 - if (Ppriv(Pr, ppriv, pprivsz) == -1) {
184 + if (Ppriv(Pr, &ppriv) == -1) {
186 185 perr(command);
187 186 Prelease(Pr, 0);
188 187 return (1);
189 188 }
190 -
191 189 sz = PRIV_PRPRIV_SIZE(ppriv);
192 190
193 191 /*
194 192 * The ppriv fields are unsigned and may overflow, so check them
195 193 * separately. Size must be word aligned, so check that too.
196 194 * Make sure size is "smallish" too.
197 195 */
198 196 if ((sz & 3) || ppriv->pr_nsets == 0 ||
199 197 sz / ppriv->pr_nsets < ppriv->pr_setsize ||
200 198 ppriv->pr_infosize > sz || sz > 1024 * 1024) {
201 199 (void) fprintf(stderr,
202 200 "%s: %s: bad PRNOTES section, size = %lx\n",
203 201 command, arg, (long)sz);
204 202 Prelease(Pr, 0);
203 + free(ppriv);
205 204 return (1);
206 205 }
207 206
208 - if (sz > pprivsz) {
209 - ppriv = realloc(ppriv, sz);
210 -
211 - if (ppriv == NULL || Ppriv(Pr, ppriv, sz) != sz) {
212 - perr(command);
213 - Prelease(Pr, 0);
214 - return (1);
215 - }
216 - pprivsz = sz;
217 - }
218 -
219 207 if (set) {
220 208 privupdate(ppriv, arg);
221 209 if (Psetpriv(Pr, ppriv) != 0) {
222 210 perr(command);
223 211 Prelease(Pr, 0);
212 + free(ppriv);
224 213 return (1);
225 214 }
226 215 Prelease(Pr, 0);
216 + free(ppriv);
227 217 return (0);
228 218 }
229 219
230 220 if (Pstate(Pr) == PS_DEAD) {
231 221 (void) printf("core '%s' of %d:\t%.70s\n",
232 222 arg, (int)Ppsinfo(Pr)->pr_pid, Ppsinfo(Pr)->pr_psargs);
233 223 pdata = Pprivinfo(Pr);
234 224 nodata = Pstate(Pr) == PS_DEAD && pdata == NULL;
235 225 } else {
236 226 (void) printf("%d:\t%.70s\n",
237 227 (int)Ppsinfo(Pr)->pr_pid, Ppsinfo(Pr)->pr_psargs);
238 228 pdata = NULL;
239 229 nodata = B_FALSE;
240 230 }
241 231
242 232 x = (char *)ppriv + sz - ppriv->pr_infosize;
243 233 while (x < (char *)ppriv + sz) {
244 234 /* LINTED: alignment */
245 235 priv_info_t *pi = (priv_info_t *)x;
246 236 priv_info_uint_t *pii;
247 237
248 238 switch (pi->priv_info_type) {
249 239 case PRIV_INFO_FLAGS:
250 240 /* LINTED: alignment */
251 241 pii = (priv_info_uint_t *)x;
252 242 (void) printf("flags =");
253 243 flags2str(pii->val);
254 244 (void) putchar('\n');
255 245 break;
256 246 default:
257 247 (void) fprintf(stderr, "%s: unknown priv_info: %d\n",
258 248 arg, pi->priv_info_type);
259 249 break;
260 250 }
261 251 if (pi->priv_info_size > ppriv->pr_infosize ||
262 252 pi->priv_info_size <= sizeof (priv_info_t) ||
263 253 (pi->priv_info_size & 3) != 0) {
264 254 (void) fprintf(stderr, "%s: bad priv_info_size: %u\n",
265 255 arg, pi->priv_info_size);
266 256 break;
267 257 }
268 258 x += pi->priv_info_size;
269 259 }
270 260
271 261 for (i = 0; i < ppriv->pr_nsets; i++) {
272 262 extern const char *__priv_getsetbynum(const void *, int);
273 263 const char *setnm = pdata ? __priv_getsetbynum(pdata, i) :
274 264 priv_getsetbynum(i);
275 265 priv_chunk_t *pc =
276 266 (priv_chunk_t *)&ppriv->pr_sets[ppriv->pr_setsize * i];
277 267
278 268
279 269 (void) printf("\t%c: ", setnm && !nodata ? *setnm : '?');
280 270 if (!nodata) {
281 271 extern char *__priv_set_to_str(void *,
282 272 const priv_set_t *, char, int);
283 273 priv_set_t *pset = (priv_set_t *)pc;
284 274
285 275 char *s;
286 276
287 277 if (pdata)
288 278 s = __priv_set_to_str(pdata, pset, ',', mode);
289 279 else
290 280 s = priv_set_to_str(pset, ',', mode);
↓ open down ↓ |
54 lines elided |
↑ open up ↑ |
291 281 (void) puts(s);
292 282 free(s);
293 283 } else {
294 284 int j;
295 285 for (j = 0; j < ppriv->pr_setsize; j++)
296 286 (void) printf("%08x", pc[j]);
297 287 (void) putchar('\n');
298 288 }
299 289 }
300 290 Prelease(Pr, 0);
291 + free(ppriv);
301 292 return (0);
302 293 }
303 294
304 295 static void
305 296 fatal(const char *s)
306 297 {
307 298 (void) fprintf(stderr, "%s: %s: %s\n", command, s, strerror(errno));
308 299 exit(3);
309 300 }
310 301
311 302 static void
312 303 perr(char *s)
313 304 {
314 305 int err = errno;
315 306
316 307 if (s != NULL)
317 308 (void) fprintf(stderr, "%s: ", procname);
318 309 else
319 310 s = procname;
320 311
321 312 errno = err;
322 313 perror(s);
323 314 }
324 315
325 316 static void
326 317 usage(void)
327 318 {
328 319 (void) fprintf(stderr,
329 320 "usage:\t%s [-v] [-S] [-D|-N] [-s spec] { pid | core } ...\n"
330 321 "\t%s -e [-D|-N] [-M] [-s spec] cmd [args ...]\n"
331 322 "\t%s -l [-v] [privilege ...]\n"
332 323 " (report, set or list process privileges)\n", command,
333 324 command, command);
334 325 exit(2);
335 326 /*NOTREACHED*/
336 327 }
337 328
338 329 /*
339 330 * Parse the privilege bits to add and/or remove from
340 331 * a privilege set.
341 332 *
342 333 * [EPIL][+-=]priv,priv,priv
343 334 */
344 335
345 336 static int
346 337 strindex(char c, const char *str)
347 338 {
348 339 const char *s;
349 340
350 341 if (islower(c))
351 342 c = toupper(c);
352 343
353 344 s = strchr(str, c);
354 345
355 346 if (s == NULL)
356 347 return (-1);
357 348 else
358 349 return (s - str);
359 350 }
360 351
361 352 static void
362 353 badspec(const char *spec)
363 354 {
364 355 (void) fprintf(stderr, "%s: bad privilege specification: \"%s\"\n",
365 356 command, spec);
366 357 exit(3);
367 358 /*NOTREACHED*/
368 359 }
369 360
370 361 /*
371 362 * For each set, you can set either add and/or
372 363 * remove or you can set assign.
373 364 */
374 365 static priv_set_t **rem, **add, **assign;
375 366 static const priv_impl_info_t *pri = NULL;
376 367 static char *sets;
377 368
378 369 static void
379 370 loadprivinfo(void)
380 371 {
381 372 int i;
382 373
383 374 if (pri != NULL)
384 375 return;
385 376
386 377 pri = getprivimplinfo();
387 378
388 379 if (pri == NULL)
389 380 fatal("getprivimplinfo");
390 381
391 382 sets = malloc(pri->priv_nsets + 1);
392 383 if (sets == NULL)
393 384 fatal("malloc");
394 385
395 386 for (i = 0; i < pri->priv_nsets; i++) {
396 387 sets[i] = *priv_getsetbynum(i);
397 388 if (islower(sets[i]))
398 389 sets[i] = toupper(sets[i]);
399 390 }
400 391
401 392 sets[pri->priv_nsets] = '\0';
402 393
403 394 rem = calloc(pri->priv_nsets, sizeof (priv_set_t *));
404 395 add = calloc(pri->priv_nsets, sizeof (priv_set_t *));
405 396 assign = calloc(pri->priv_nsets, sizeof (priv_set_t *));
406 397 if (rem == NULL || add == NULL || assign == NULL)
407 398 fatal("calloc");
408 399 }
409 400
410 401 static int
411 402 parsespec(const char *spec)
412 403 {
413 404 char *p;
414 405 const char *q;
415 406 int count;
416 407 priv_set_t ***toupd;
417 408 priv_set_t *upd;
418 409 int i;
419 410 boolean_t freeupd = B_TRUE;
420 411
421 412 if (pri == NULL)
422 413 loadprivinfo();
423 414
424 415 p = strpbrk(spec, "+-=");
425 416
426 417 if (p == NULL || p - spec > pri->priv_nsets)
427 418 badspec(spec);
428 419
429 420 if (p[1] == '\0' || (upd = priv_str_to_set(p + 1, ",", NULL)) == NULL)
430 421 badspec(p + 1);
431 422
432 423 count = p - spec;
433 424 switch (*p) {
434 425 case '+':
435 426 toupd = &add;
436 427 break;
437 428 case '-':
438 429 toupd = &rem;
439 430 priv_inverse(upd);
440 431 break;
441 432 case '=':
442 433 toupd = &assign;
443 434 break;
444 435 }
445 436
446 437 /* Update all sets? */
447 438 if (count == 0 || *spec == 'a' || *spec == 'A') {
448 439 count = pri->priv_nsets;
449 440 q = sets;
450 441 } else
451 442 q = spec;
452 443
453 444 for (i = 0; i < count; i++) {
454 445 int ind = strindex(q[i], sets);
455 446
456 447 if (ind == -1)
457 448 badspec(spec);
458 449
459 450 /* Assign is mutually exclusive with add/remove and itself */
460 451 if (((toupd == &rem || toupd == &add) && assign[ind] != NULL) ||
461 452 (toupd == &assign && (assign[ind] != NULL ||
462 453 rem[ind] != NULL || add[ind] != NULL))) {
463 454 (void) fprintf(stderr, "%s: conflicting spec: %s\n",
464 455 command, spec);
465 456 exit(1);
466 457 }
467 458 if ((*toupd)[ind] != NULL) {
468 459 if (*p == '-')
469 460 priv_intersect(upd, (*toupd)[ind]);
470 461 else
471 462 priv_union(upd, (*toupd)[ind]);
472 463 } else {
473 464 (*toupd)[ind] = upd;
474 465 freeupd = B_FALSE;
475 466 }
476 467 }
477 468 if (freeupd)
478 469 priv_freeset(upd);
479 470 return (0);
480 471 }
481 472
482 473 static void
483 474 privupdate(prpriv_t *pr, const char *arg)
484 475 {
485 476 int i;
486 477
487 478 if (sets != NULL) {
488 479 for (i = 0; i < pri->priv_nsets; i++) {
489 480 priv_set_t *target =
490 481 (priv_set_t *)&pr->pr_sets[pr->pr_setsize * i];
491 482 if (rem[i] != NULL)
492 483 priv_intersect(rem[i], target);
493 484 if (add[i] != NULL)
494 485 priv_union(add[i], target);
495 486 if (assign[i] != NULL)
496 487 priv_copyset(assign[i], target);
497 488 }
498 489 }
499 490
500 491 if (Doff || Don || pfexec || xpol) {
501 492 priv_info_uint_t *pii;
502 493 int sz = PRIV_PRPRIV_SIZE(pr);
503 494 char *x = (char *)pr + PRIV_PRPRIV_INFO_OFFSET(pr);
504 495 uint32_t fl = 0;
505 496
506 497 while (x < (char *)pr + sz) {
507 498 /* LINTED: alignment */
508 499 priv_info_t *pi = (priv_info_t *)x;
509 500
510 501 if (pi->priv_info_type == PRIV_INFO_FLAGS) {
511 502 /* LINTED: alignment */
512 503 pii = (priv_info_uint_t *)x;
513 504 fl = pii->val;
514 505 goto done;
515 506 }
516 507 if (pi->priv_info_size > pr->pr_infosize ||
517 508 pi->priv_info_size <= sizeof (priv_info_t) ||
518 509 (pi->priv_info_size & 3) != 0)
519 510 break;
520 511 x += pi->priv_info_size;
521 512 }
522 513 (void) fprintf(stderr,
523 514 "%s: cannot find privilege flags to set\n", arg);
524 515 pr->pr_infosize = 0;
525 516 return;
526 517 done:
527 518
528 519 pr->pr_infosize = sizeof (priv_info_uint_t);
529 520 /* LINTED: alignment */
530 521 pii = (priv_info_uint_t *)
531 522 ((char *)pr + PRIV_PRPRIV_INFO_OFFSET(pr));
532 523
533 524 if (Don)
534 525 fl |= PRIV_DEBUG;
535 526 if (Doff)
536 527 fl &= ~PRIV_DEBUG;
537 528 if (pfexec)
538 529 fl |= PRIV_PFEXEC;
539 530 if (xpol)
540 531 fl |= PRIV_XPOLICY;
541 532
542 533 pii->info.priv_info_size = sizeof (*pii);
543 534 pii->info.priv_info_type = PRIV_INFO_FLAGS;
544 535 pii->val = fl;
545 536 } else {
546 537 pr->pr_infosize = 0;
547 538 }
548 539 }
549 540
550 541 static void
551 542 privupdate_self(void)
552 543 {
553 544 int set;
554 545
555 546 if (mac_aware) {
556 547 if (setpflags(NET_MAC_AWARE, 1) != 0)
557 548 fatal("setpflags(NET_MAC_AWARE)");
558 549 if (setpflags(NET_MAC_AWARE_INHERIT, 1) != 0)
559 550 fatal("setpflags(NET_MAC_AWARE_INHERIT)");
560 551 }
561 552 if (pfexec) {
562 553 if (setpflags(PRIV_PFEXEC, 1) != 0)
563 554 fatal("setpflags(PRIV_PFEXEC)");
564 555 }
565 556
566 557 if (sets != NULL) {
567 558 priv_set_t *target = priv_allocset();
568 559
569 560 if (target == NULL)
570 561 fatal("priv_allocet");
571 562
572 563 set = priv_getsetbyname(PRIV_INHERITABLE);
573 564 if (rem[set] != NULL || add[set] != NULL ||
574 565 assign[set] != NULL) {
575 566 (void) getppriv(PRIV_INHERITABLE, target);
576 567 if (rem[set] != NULL)
577 568 priv_intersect(rem[set], target);
578 569 if (add[set] != NULL)
579 570 priv_union(add[set], target);
580 571 if (assign[set] != NULL)
581 572 priv_copyset(assign[set], target);
582 573 if (setppriv(PRIV_SET, PRIV_INHERITABLE, target) != 0)
583 574 fatal("setppriv(Inheritable)");
584 575 }
585 576 set = priv_getsetbyname(PRIV_LIMIT);
586 577 if (rem[set] != NULL || add[set] != NULL ||
587 578 assign[set] != NULL) {
588 579 (void) getppriv(PRIV_LIMIT, target);
589 580 if (rem[set] != NULL)
590 581 priv_intersect(rem[set], target);
591 582 if (add[set] != NULL)
592 583 priv_union(add[set], target);
593 584 if (assign[set] != NULL)
594 585 priv_copyset(assign[set], target);
595 586 if (setppriv(PRIV_SET, PRIV_LIMIT, target) != 0)
596 587 fatal("setppriv(Limit)");
597 588 }
598 589 priv_freeset(target);
599 590 }
600 591
601 592 if (Doff || Don)
602 593 (void) setpflags(PRIV_DEBUG, Don ? 1 : 0);
603 594 if (xpol)
604 595 (void) setpflags(PRIV_XPOLICY, 1);
605 596 if (pfexec)
606 597 (void) setpflags(PRIV_PFEXEC, 1);
607 598 }
608 599
609 600 static int
610 601 dopriv(const char *p)
611 602 {
612 603 (void) puts(p);
613 604 if (verb) {
614 605 char *text = priv_gettext(p);
615 606 char *p, *q;
616 607 if (text == NULL)
617 608 return (1);
618 609 for (p = text; q = strchr(p, '\n'); p = q + 1) {
619 610 *q = '\0';
620 611 (void) printf("\t%s\n", p);
621 612 }
622 613 free(text);
623 614 }
624 615 return (0);
625 616 }
626 617
627 618 static int
628 619 dumppriv(char **argv)
629 620 {
630 621 int rc = 0;
631 622 const char *pname;
632 623 int i;
633 624
634 625 if (argv[0] == NULL) {
635 626 for (i = 0; ((pname = priv_getbynum(i++)) != NULL); )
636 627 rc += dopriv(pname);
637 628 } else {
638 629 for (; *argv; argv++) {
639 630 priv_set_t *pset = priv_str_to_set(*argv, ",", NULL);
640 631
641 632 if (pset == NULL) {
642 633 (void) fprintf(stderr, "%s: %s: bad privilege"
643 634 " list\n", command, *argv);
644 635 rc++;
645 636 continue;
646 637 }
647 638 for (i = 0; ((pname = priv_getbynum(i++)) != NULL); )
648 639 if (priv_ismember(pset, pname))
649 640 rc += dopriv(pname);
650 641 }
651 642 }
652 643 return (rc);
653 644 }
654 645
655 646 static struct {
656 647 int flag;
657 648 char *name;
658 649 } flags[] = {
659 650 { PRIV_DEBUG, "PRIV_DEBUG" },
660 651 { PRIV_AWARE, "PRIV_AWARE" },
661 652 { PRIV_AWARE_INHERIT, "PRIV_AWARE_INHERIT" },
662 653 { PRIV_AWARE_RESET, "PRIV_AWARE_RESET" },
663 654 { PRIV_XPOLICY, "PRIV_XPOLICY" },
664 655 { PRIV_PFEXEC, "PRIV_PFEXEC" },
665 656 { NET_MAC_AWARE, "NET_MAC_AWARE" },
666 657 { NET_MAC_AWARE_INHERIT, "NET_MAC_AWARE_INHERIT" },
667 658 };
668 659
669 660 /*
670 661 * Print flags preceeded by a space.
671 662 */
672 663 static void
673 664 flags2str(uint_t pflags)
674 665 {
675 666 char c = ' ';
676 667 int i;
677 668
678 669 if (pflags == 0) {
679 670 (void) fputs(" <none>", stdout);
680 671 return;
681 672 }
682 673 for (i = 0; i < sizeof (flags)/sizeof (flags[0]) && pflags != 0; i++) {
683 674 if ((pflags & flags[i].flag) != 0) {
684 675 (void) printf("%c%s", c, flags[i].name);
685 676 pflags &= ~flags[i].flag;
686 677 c = '|';
687 678 }
688 679 }
689 680 if (pflags != 0)
690 681 (void) printf("%c<0x%x>", c, pflags);
691 682 }
↓ open down ↓ |
381 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX