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. 6 * 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. 10 */ 11 12 /* Copyright 2015, Richard Lowe. */ 13 14 #include "lint.h" 15 16 #include <errno.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <strings.h> 21 22 #include <sys/proc.h> 23 #include <sys/procset.h> 24 #include <sys/syscall.h> 25 #include <sys/secflags.h> 26 27 extern int __psecflagsset(procset_t *, psecflagwhich_t, secflagdelta_t *); 28 29 int 30 psecflags(idtype_t idtype, id_t id, psecflagwhich_t which, 31 secflagdelta_t *delta) 32 { 33 procset_t procset; 34 35 setprocset(&procset, POP_AND, idtype, id, P_ALL, 0); 36 37 return (__psecflagsset(&procset, which, delta)); 38 } 39 40 int 41 secflags_parse(const secflagset_t *defaults, const char *flags, 42 secflagdelta_t *ret) 43 { 44 char *flag; 45 char *s, *ss; 46 boolean_t current = B_FALSE; 47 48 /* Guarantee a clean base */ 49 bzero(ret, sizeof (*ret)); 50 51 if ((ss = s = strdup(flags)) == NULL) 52 return (-1); /* errno set for us */ 53 54 55 while ((flag = strsep(&s, ",")) != NULL) { 56 secflag_t sf = 0; 57 boolean_t del = B_FALSE; 58 59 if (strcasecmp(flag, "default") == 0) { 60 if (defaults != NULL) { 61 secflags_union(&ret->psd_add, defaults); 62 } else { 63 free(ss); 64 errno = EINVAL; 65 return (-1); 66 } 67 continue; 68 } else if (strcasecmp(flag, "all") == 0) { 69 secflags_fullset(&ret->psd_add); 70 continue; 71 } else if (strcasecmp(flag, "none") == 0) { 72 secflags_fullset(&ret->psd_rem); 73 continue; 74 } else if (strcasecmp(flag, "current") == 0) { 75 current = B_TRUE; 76 continue; 77 } 78 79 if ((flag[0] == '-') || (flag[0] == '!')) { 80 flag++; 81 del = B_TRUE; 82 } else if (flag[0] == '+') { 83 flag++; 84 } 85 86 if ((secflag_by_name(flag, &sf)) != B_TRUE) { 87 free(ss); 88 errno = EINVAL; 89 return (-1); 90 } 91 92 if (del) 93 secflag_set(&(ret->psd_rem), sf); 94 else 95 secflag_set(&(ret->psd_add), sf); 96 } 97 98 /* 99 * If we're not using the current flags, this is strict assignment. 100 * Negatives "win". 101 */ 102 if (!current) { 103 secflags_copy(&ret->psd_assign, &ret->psd_add); 104 secflags_difference(&ret->psd_assign, &ret->psd_rem); 105 ret->psd_ass_active = B_TRUE; 106 secflags_zero(&ret->psd_add); 107 secflags_zero(&ret->psd_rem); 108 } 109 110 free(ss); 111 return (0); 112 }