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 }