1 /* 2 * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. 3 */ 4 5 /* Solaris includes. */ 6 #include <priv.h> 7 #include <ctype.h> 8 9 /* Perl includes. */ 10 #include "EXTERN.h" 11 #include "perl.h" 12 #include "XSUB.h" 13 14 #define IVCONST(s, c) newCONSTSUB(s, #c, newSViv((int)(intptr_t)c)); 15 #define POFF (sizeof ("PRIV_") - 1) 16 17 #define RETPRIVSET(set) \ 18 ST(0) = sv_newmortal(); \ 19 sv_setref_pv(ST(0), "Sun::Solaris::Privilege::PrivsetPtr", \ 20 (void*)(set)); \ 21 SvREADONLY_on(SvRV(ST(0))) 22 23 typedef int sysret; 24 25 typedef priv_set_t Sun__Solaris__Privilege__Privset; 26 27 static priv_set_t * 28 dupset(const priv_set_t *s) 29 { 30 priv_set_t *new = priv_allocset(); 31 if (new == NULL) 32 return (NULL); 33 34 priv_copyset(s, new); 35 return (new); 36 } 37 38 /* 39 * Automatically derive the #define constant from the constant value. 40 * This is the uppercase value of the constant with "PRIV_" prepended. 41 * The (name, value) pair computed in that way is stored twice: 42 * once as constant subroutine in the module's hash table. 43 * once as (key, value) in a hash table. 44 */ 45 46 static void 47 PRIVconst(HV *sym, HV *var, const char *name) 48 { 49 char upname[128]; 50 ssize_t len; 51 int i; 52 53 len = snprintf(upname, sizeof (upname), "PRIV_%s", name); 54 if (len >= sizeof (upname)) 55 return; 56 57 for (i = POFF; i < len; i++) 58 upname[i] = toupper(upname[i]); 59 newCONSTSUB(sym, upname, newSVpv(name, len - POFF)); 60 hv_store(var, upname, len, newSVpv(name, len - POFF), 0); 61 } 62 63 /* 64 * The XS code exported to perl is below here. Note that the XS preprocessor 65 * has its own commenting syntax, so all comments from this point on are in 66 * that form. 67 * 68 * Inside perl, privilege sets are represented as expanded strings; 69 * privileges and privilege sets are only known by name. 70 */ 71 72 MODULE = Sun::Solaris::Privilege PACKAGE = Sun::Solaris::Privilege 73 PROTOTYPES: ENABLE 74 75 # 76 # Define any constants that need to be exported. By doing it this way we can 77 # avoid the overhead of using the DynaLoader package, and in addition constants 78 # defined using this mechanism are eligible for inlining by the perl 79 # interpreter at compile time. 80 # 81 BOOT: 82 { 83 HV *stash; 84 HV *privs; 85 HV *privsets; 86 const char *p; 87 int i; 88 89 stash = gv_stashpv("Sun::Solaris::Privilege", TRUE); 90 91 /* 92 * Global constants 93 */ 94 IVCONST(stash, PRIV_STR_PORT); 95 IVCONST(stash, PRIV_STR_LIT); 96 IVCONST(stash, PRIV_STR_SHORT); 97 IVCONST(stash, PRIV_ALLSETS); 98 IVCONST(stash, PRIV_DEBUG); 99 IVCONST(stash, PRIV_AWARE); 100 IVCONST(stash, PRIV_ON); 101 IVCONST(stash, PRIV_OFF); 102 IVCONST(stash, PRIV_SET); 103 104 /* 105 * %PRIVILEGES hash and the privilege constants 106 */ 107 privs = perl_get_hv("Sun::Solaris::Privilege::PRIVILEGES", TRUE); 108 for (i = 0; (p = priv_getbynum(i++)) != NULL; ) 109 PRIVconst(stash, privs, p); 110 111 /* 112 * %PRIVSETS hash and the privset constants 113 */ 114 privsets = perl_get_hv("Sun::Solaris::Privilege::PRIVSETS", TRUE); 115 for (i = 0; (p = priv_getsetbynum(i++)) != NULL; ) 116 PRIVconst(stash, privsets, p); 117 } 118 119 120 Sun::Solaris::Privilege::Privset * 121 getppriv(which) 122 const char *which; 123 CODE: 124 RETVAL = priv_allocset(); 125 if (getppriv(which, RETVAL) != 0) { 126 priv_freeset(RETVAL); 127 XSRETURN_UNDEF; 128 } else { 129 RETPRIVSET(RETVAL); 130 } 131 132 sysret 133 setppriv(op, which, set) 134 int op; 135 const char *which; 136 Sun::Solaris::Privilege::Privset *set; 137 138 Sun::Solaris::Privilege::Privset * 139 priv_emptyset() 140 CODE: 141 RETVAL = priv_allocset(); 142 if (RETVAL == NULL) { 143 XSRETURN_UNDEF; 144 } 145 priv_emptyset(RETVAL); 146 RETPRIVSET(RETVAL); 147 148 Sun::Solaris::Privilege::Privset * 149 priv_fillset() 150 CODE: 151 RETVAL = priv_allocset(); 152 if (RETVAL == NULL) { 153 XSRETURN_UNDEF; 154 } 155 priv_fillset(RETVAL); 156 RETPRIVSET(RETVAL); 157 158 boolean_t 159 priv_isemptyset(set) 160 Sun::Solaris::Privilege::Privset *set; 161 162 boolean_t 163 priv_isfullset(set) 164 Sun::Solaris::Privilege::Privset *set; 165 166 boolean_t 167 priv_isequalset(set1, set2) 168 Sun::Solaris::Privilege::Privset *set1; 169 Sun::Solaris::Privilege::Privset *set2; 170 171 boolean_t 172 priv_issubset(set1, set2) 173 Sun::Solaris::Privilege::Privset *set1; 174 Sun::Solaris::Privilege::Privset *set2; 175 176 boolean_t 177 priv_ismember(set, priv) 178 Sun::Solaris::Privilege::Privset *set; 179 const char *priv; 180 181 boolean_t 182 priv_ineffect(priv) 183 const char *priv; 184 185 Sun::Solaris::Privilege::Privset * 186 priv_intersect(set1, set2) 187 Sun::Solaris::Privilege::Privset *set1; 188 Sun::Solaris::Privilege::Privset *set2; 189 CODE: 190 RETVAL = dupset(set2); 191 if (RETVAL == NULL) { 192 XSRETURN_UNDEF; 193 } 194 priv_intersect(set1, RETVAL); 195 RETPRIVSET(RETVAL); 196 197 Sun::Solaris::Privilege::Privset * 198 priv_union(set1, set2) 199 Sun::Solaris::Privilege::Privset *set1; 200 Sun::Solaris::Privilege::Privset *set2; 201 CODE: 202 RETVAL = dupset(set2); 203 if (RETVAL == NULL) { 204 XSRETURN_UNDEF; 205 } 206 priv_union(set1, RETVAL); 207 RETPRIVSET(RETVAL); 208 209 Sun::Solaris::Privilege::Privset * 210 priv_inverse(set1) 211 Sun::Solaris::Privilege::Privset *set1; 212 CODE: 213 RETVAL = dupset(set1); 214 if (RETVAL == NULL) { 215 XSRETURN_UNDEF; 216 } 217 priv_inverse(RETVAL); 218 RETPRIVSET(RETVAL); 219 220 221 sysret 222 priv_addset(set, priv) 223 Sun::Solaris::Privilege::Privset *set; 224 const char *priv; 225 226 Sun::Solaris::Privilege::Privset * 227 priv_copyset(set1) 228 Sun::Solaris::Privilege::Privset *set1; 229 CODE: 230 RETVAL = dupset(set1); 231 if (RETVAL == NULL) { 232 XSRETURN_UNDEF; 233 } 234 RETPRIVSET(RETVAL); 235 236 237 sysret 238 priv_delset(set, priv) 239 Sun::Solaris::Privilege::Privset *set; 240 const char *priv; 241 242 const char * 243 priv_getbynum(i) 244 int i; 245 246 const char * 247 priv_getsetbynum(i) 248 int i; 249 250 char * 251 priv_set_to_str(s, c, f) 252 Sun::Solaris::Privilege::Privset *s; 253 char c; 254 int f; 255 CLEANUP: 256 free(RETVAL); 257 258 Sun::Solaris::Privilege::Privset * 259 priv_str_to_set(buf, sep); 260 const char *buf; 261 const char *sep; 262 CODE: 263 RETVAL = priv_str_to_set(buf, sep, NULL); 264 if (RETVAL == NULL) { 265 XSRETURN_UNDEF; 266 } 267 RETPRIVSET(RETVAL); 268 269 char * 270 priv_gettext(priv) 271 const char *priv 272 CLEANUP: 273 free(RETVAL); 274 275 sysret 276 setpflags(flag, val) 277 uint_t flag; 278 uint_t val; 279 280 sysret 281 getpflags(flag) 282 uint_t flag; 283 284 MODULE = Sun::Solaris::Privilege PACKAGE = Sun::Solaris::Privilege::PrivsetPtr PREFIX = Privilege_ 285 286 void 287 Privilege_DESTROY(ps) 288 Sun::Solaris::Privilege::Privset *ps; 289 CODE: 290 priv_freeset(ps); 291